GCC Code Coverage Report


Directory: ./
File: sql/sql_optimizer.cc
Date: 2022-12-13 11:44:05
Exec Total Coverage
Lines: 4247 4409 96.3%
Branches: 5411 7293 74.2%

Line Branch Exec Source
1 /* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /**
24 @file
25
26 @brief Optimize query expressions: Make optimal table join order, select
27 optimal access methods per table, apply grouping, sorting and
28 limit processing.
29
30 @defgroup Query_Optimizer Query Optimizer
31 @{
32 */
33
34 #include "sql/sql_optimizer.h"
35 #include "sql/sql_optimizer_internal.h"
36
37 #include <limits.h>
38 #include <algorithm>
39 #include <atomic>
40 #include <deque>
41 #include <new>
42 #include <string>
43 #include <utility>
44 #include <vector>
45
46 #include "field_types.h" // enum_field_types
47 #include "ft_global.h"
48 #include "m_ctype.h"
49 #include "mem_root_deque.h"
50 #include "memory_debugging.h"
51 #include "my_bit.h" // my_count_bits
52 #include "my_bitmap.h"
53 #include "my_compiler.h"
54 #include "my_dbug.h"
55 #include "my_inttypes.h"
56 #include "my_sqlcommand.h"
57 #include "my_sys.h"
58 #include "mysql/udf_registration_types.h"
59 #include "mysql_com.h"
60 #include "mysqld_error.h"
61 #include "sql/check_stack.h"
62 #include "sql/current_thd.h"
63 #include "sql/debug_sync.h" // DEBUG_SYNC
64 #include "sql/derror.h" // ER_THD
65 #include "sql/enum_query_type.h"
66 #include "sql/error_handler.h" // Functional_index_error_handler
67 #include "sql/handler.h"
68 #include "sql/item.h"
69 #include "sql/item_cmpfunc.h"
70 #include "sql/item_func.h"
71 #include "sql/item_row.h"
72 #include "sql/item_subselect.h"
73 #include "sql/item_sum.h" // Item_sum
74 #include "sql/iterators/basic_row_iterators.h"
75 #include "sql/iterators/timing_iterator.h"
76 #include "sql/join_optimizer/access_path.h"
77 #include "sql/join_optimizer/join_optimizer.h"
78 #include "sql/key.h"
79 #include "sql/key_spec.h"
80 #include "sql/lock.h" // mysql_unlock_some_tables
81 #include "sql/mysqld.h" // stage_optimizing
82 #include "sql/nested_join.h"
83 #include "sql/opt_costmodel.h"
84 #include "sql/opt_explain.h" // join_type_str
85 #include "sql/opt_hints.h" // hint_table_state
86 #include "sql/opt_trace.h" // Opt_trace_object
87 #include "sql/opt_trace_context.h"
88 #include "sql/parse_tree_node_base.h"
89 #include "sql/parser_yystype.h"
90 #include "sql/query_options.h"
91 #include "sql/query_result.h"
92 #include "sql/range_optimizer/partition_pruning.h"
93 #include "sql/range_optimizer/path_helpers.h"
94 #include "sql/range_optimizer/range_optimizer.h"
95 #include "sql/sql_base.h" // init_ftfuncs
96 #include "sql/sql_bitmap.h"
97 #include "sql/sql_class.h"
98 #include "sql/sql_const.h"
99 #include "sql/sql_const_folding.h"
100 #include "sql/sql_error.h"
101 #include "sql/sql_join_buffer.h" // JOIN_CACHE
102 #include "sql/sql_planner.h" // calculate_condition_filter
103 #include "sql/sql_test.h" // print_where
104 #include "sql/sql_tmp_table.h"
105 #include "sql/system_variables.h"
106 #include "sql/table.h"
107 #include "sql/thd_raii.h"
108 #include "sql/window.h"
109 #include "sql_string.h"
110 #include "template_utils.h"
111
112 using std::max;
113 using std::min;
114
115 const char *antijoin_null_cond = "<ANTIJOIN-NULL>";
116
117 static bool optimize_semijoin_nests_for_materialization(JOIN *join);
118 static void calculate_materialization_costs(JOIN *join, TABLE_LIST *sj_nest,
119 uint n_tables,
120 Semijoin_mat_optimize *sjm);
121 static bool make_join_query_block(JOIN *join, Item *item);
122 static bool list_contains_unique_index(JOIN_TAB *tab,
123 bool (*find_func)(Field *, void *),
124 void *data);
125 static bool find_field_in_item_list(Field *field, void *data);
126 static bool find_field_in_order_list(Field *field, void *data);
127 static TABLE *get_sort_by_table(ORDER *a, ORDER *b, TABLE_LIST *tables);
128 static void trace_table_dependencies(Opt_trace_context *trace,
129 JOIN_TAB *join_tabs, uint table_count);
130 static bool update_ref_and_keys(THD *thd, Key_use_array *keyuse,
131 JOIN_TAB *join_tab, uint tables, Item *cond,
132 table_map normal_tables,
133 Query_block *query_block,
134 SARGABLE_PARAM **sargables);
135 static bool pull_out_semijoin_tables(JOIN *join);
136 static void add_loose_index_scan_and_skip_scan_keys(JOIN *join,
137 JOIN_TAB *join_tab);
138 static ha_rows get_quick_record_count(THD *thd, JOIN_TAB *tab, ha_rows limit);
139 static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables,
140 table_map *cached_eq_ref_tables,
141 table_map *eq_ref_tables);
142 static bool setup_join_buffering(JOIN_TAB *tab, JOIN *join, uint no_jbuf_after);
143
144 static bool test_if_skip_sort_order(JOIN_TAB *tab, ORDER_with_src &order,
145 ha_rows select_limit, const bool no_changes,
146 const Key_map *map, int *best_idx);
147
148 static Item_func_match *test_if_ft_index_order(ORDER *order);
149
150 static uint32 get_key_length_tmp_table(Item *item);
151 static bool can_switch_from_ref_to_range(THD *thd, JOIN_TAB *tab,
152 enum_order ordering,
153 bool recheck_range);
154
155 static bool has_not_null_predicate(Item *cond, Item_field *not_null_item);
156
157 9125947 JOIN::JOIN(THD *thd_arg, Query_block *select)
158 9125947 : query_block(select),
159 9125947 thd(thd_arg),
160 // @todo Can this be substituted with select->is_explicitly_grouped()?
161 18251936 grouped(select->is_explicitly_grouped()),
162 // Inner tables may always be considered to be constant:
163 9125968 const_table_map(INNER_TABLE_BIT),
164 9125968 found_const_table_map(INNER_TABLE_BIT),
165 // Needed in case optimizer short-cuts, set properly in
166 // make_tmp_tables_info()
167 9125968 fields(&select->fields),
168 9125977 tmp_table_param(thd_arg->mem_root),
169 9125954 lock(thd->lock),
170 // @todo Can this be substituted with select->is_implicitly_grouped()?
171 9125954 implicit_grouping(select->is_implicitly_grouped()),
172 9125966 select_distinct(select->is_distinct()),
173 9125974 keyuse_array(thd->mem_root),
174 9125955 order(select->order_list.first, ESC_ORDER_BY),
175 9125954 group_list(select->group_list.first, ESC_GROUP_BY),
176 9125953 m_windows(select->m_windows),
177 /*
178 Those four members are meaningless before JOIN::optimize(), so force a
179 crash if they are used before that.
180 */
181 9125952 where_cond(reinterpret_cast<Item *>(1)),
182 9125952 having_cond(reinterpret_cast<Item *>(1)),
183 9125952 having_for_explain(reinterpret_cast<Item *>(1)),
184 9125952 tables_list(reinterpret_cast<TABLE_LIST *>(1)),
185 9125952 current_ref_item_slice(REF_SLICE_SAVED_BASE),
186
2/4
✓ Branch 0 taken 9125954 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9125955 times.
✗ Branch 3 not taken.
36503845 with_json_agg(select->json_agg_func_used()) {
187 9125963 rollup_state = RollupState::NONE;
188
2/2
✓ Branch 0 taken 553479 times.
✓ Branch 1 taken 8572484 times.
9125963 if (select->order_list.first) explain_flags.set(ESC_ORDER_BY, ESP_EXISTS);
189
2/2
✓ Branch 0 taken 23651 times.
✓ Branch 1 taken 9102312 times.
9125963 if (select->group_list.first) explain_flags.set(ESC_GROUP_BY, ESP_EXISTS);
190
2/2
✓ Branch 0 taken 4231 times.
✓ Branch 1 taken 9121749 times.
9125963 if (select->is_distinct()) explain_flags.set(ESC_DISTINCT, ESP_EXISTS);
191
2/2
✓ Branch 0 taken 2450 times.
✓ Branch 1 taken 9123530 times.
9125980 if (m_windows.elements > 0) explain_flags.set(ESC_WINDOWING, ESP_EXISTS);
192 // Calculate the number of groups
193
2/2
✓ Branch 0 taken 31362 times.
✓ Branch 1 taken 9125965 times.
9157327 for (ORDER *group = group_list.order; group; group = group->next)
194 31362 send_group_parts++;
195 9125965 }
196
197 523901 bool JOIN::alloc_ref_item_slice(THD *thd_arg, int sliceno) {
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 523901 times.
523901 assert(sliceno > 0);
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 523901 times.
523901 assert(ref_items[sliceno].is_null());
200 523901 size_t count = ref_items[0].size();
201 523900 Item **slice = thd_arg->mem_root->ArrayAlloc<Item *>(count);
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 523901 times.
523901 if (slice == nullptr) return true;
203 523901 ref_items[sliceno] = Ref_item_array(slice, count);
204 523901 return false;
205 }
206
207 9008570 bool JOIN::alloc_indirection_slices() {
208 9008570 const int num_slices = REF_SLICE_WIN_1 + m_windows.elements;
209
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9008570 times.
9008570 assert(ref_items == nullptr);
211 9008570 ref_items = (*THR_MALLOC)->ArrayAlloc<Ref_item_array>(num_slices);
212
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9008609 times.
9008609 if (ref_items == nullptr) return true;
213
214 9008611 tmp_fields =
215 9008609 (*THR_MALLOC)
216 9008616 ->ArrayAlloc<mem_root_deque<Item *>>(num_slices, *THR_MALLOC);
217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9008611 times.
9008611 if (tmp_fields == nullptr) return true;
218
219 9008611 return false;
220 }
221
222 /**
223 The List<Item_equal> in COND_EQUAL partially overlaps with the argument list
224 in various Item_cond via C-style casts. However, the hypergraph optimizer can
225 modify the lists in Item_cond (by calling compile()), causing an Item_equal to
226 be replaced with Item_func_eq, and this can cause a List<Item_equal> not to
227 contain Item_equal pointers anymore. This is is obviously bad if anybody wants
228 to actually look into these lists after optimization (in particular, NDB
229 wants this).
230
231 Since untangling this spaghetti seems very hard, we solve it by brute force:
232 Make a copy of all the COND_EQUAL lists, so that they no longer reach into the
233 Item_cond. This allows us to modify the Item_cond at will.
234 */
235 107 static void SaveCondEqualLists(COND_EQUAL *cond_equal) {
236
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 11 times.
107 if (cond_equal == nullptr) {
237 96 return;
238 }
239 11 List<Item_equal> copy;
240
5/8
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 11 times.
20 for (Item_equal &item : cond_equal->current_level) {
241
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 copy.push_back(&item);
242 }
243 11 cond_equal->current_level = std::move(copy);
244
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 SaveCondEqualLists(cond_equal->upper_levels);
245 }
246
247 /**
248 Optimizes one query block into a query execution plan (QEP.)
249
250 This is the entry point to the query optimization phase. This phase
251 applies both logical (equivalent) query rewrites, cost-based join
252 optimization, and rule-based access path selection. Once an optimal
253 plan is found, the member function creates/initializes all
254 structures needed for query execution. The main optimization phases
255 are outlined below:
256
257 -# Logical transformations:
258 - Outer to inner joins transformation.
259 - Equality/constant propagation.
260 - Partition pruning.
261 - COUNT(*), MIN(), MAX() constant substitution in case of
262 implicit grouping.
263 - ORDER BY optimization.
264 -# Perform cost-based optimization of table order and access path
265 selection. See JOIN::make_join_plan()
266 -# Post-join order optimization:
267 - Create optimal table conditions from the where clause and the
268 join conditions.
269 - Inject outer-join guarding conditions.
270 - Adjust data access methods after determining table condition
271 (several times.)
272 - Optimize ORDER BY/DISTINCT.
273 -# Code generation
274 - Set data access functions.
275 - Try to optimize away sorting/distinct.
276 - Setup temporary table usage for grouping and/or sorting.
277
278 @retval false Success.
279 @retval true Error, error code saved in member JOIN::error.
280 */
281 9008627 bool JOIN::optimize(bool finalize_access_paths) {
282
1/2
✓ Branch 0 taken 9008677 times.
✗ Branch 1 not taken.
9008627 DBUG_TRACE;
283
284 9008677 uint no_jbuf_after = UINT_MAX;
285
286
5/6
✓ Branch 0 taken 1889050 times.
✓ Branch 1 taken 7119627 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1889050 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
9008677 assert(query_block->leaf_table_count == 0 ||
287 thd->lex->is_query_tables_locked() ||
288 query_block == query_expression()->fake_query_block);
289
4/6
✓ Branch 0 taken 9008649 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 9008653 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9008656 times.
✗ Branch 5 not taken.
9008678 assert(tables == 0 && primary_tables == 0 && tables_list == (TABLE_LIST *)1);
290
291 // to prevent double initialization on EXPLAIN
292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9008656 times.
9008656 if (optimized) return false;
293
294
3/4
✓ Branch 0 taken 8991033 times.
✓ Branch 1 taken 17623 times.
✓ Branch 2 taken 8991052 times.
✗ Branch 3 not taken.
9008656 DEBUG_SYNC(thd, "before_join_optimize");
295
296
1/2
✓ Branch 0 taken 9008671 times.
✗ Branch 1 not taken.
9008675 THD_STAGE_INFO(thd, stage_optimizing);
297
298 9008671 Opt_trace_context *const trace = &thd->opt_trace;
299
1/2
✓ Branch 0 taken 9008675 times.
✗ Branch 1 not taken.
9008671 Opt_trace_object trace_wrapper(trace);
300
1/2
✓ Branch 0 taken 9008672 times.
✗ Branch 1 not taken.
9008675 Opt_trace_object trace_optimize(trace, "join_optimization");
301
1/2
✓ Branch 0 taken 9008664 times.
✗ Branch 1 not taken.
9008672 trace_optimize.add_select_number(query_block->select_number);
302
1/2
✓ Branch 0 taken 9008646 times.
✗ Branch 1 not taken.
9008664 Opt_trace_array trace_steps(trace, "steps");
303
304
1/2
✓ Branch 0 taken 9008676 times.
✗ Branch 1 not taken.
9008646 count_field_types(query_block, &tmp_table_param, *fields, false, false);
305
306
5/6
✓ Branch 0 taken 371697 times.
✓ Branch 1 taken 8636979 times.
✓ Branch 2 taken 351640 times.
✓ Branch 3 taken 20057 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 351640 times.
9008676 assert(tmp_table_param.sum_func_count == 0 || !group_list.empty() ||
307 implicit_grouping);
308
309 9008676 const bool has_windows = m_windows.elements != 0;
310
311
7/8
✓ Branch 0 taken 2450 times.
✓ Branch 1 taken 9006226 times.
✓ Branch 2 taken 2450 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 53 times.
✓ Branch 5 taken 2397 times.
✓ Branch 6 taken 53 times.
✓ Branch 7 taken 9008623 times.
9008676 if (has_windows && Window::setup_windows2(thd, &m_windows))
312 53 return true; /* purecov: inspected */
313
314
5/8
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 9008246 times.
✓ Branch 2 taken 377 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 377 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 9008623 times.
9008623 if (query_block->olap == ROLLUP_TYPE && optimize_rollup())
315 return true; /* purecov: inspected */
316
317
2/4
✓ Branch 0 taken 9008620 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9008620 times.
9008623 if (alloc_func_list()) return true; /* purecov: inspected */
318
319
2/4
✓ Branch 0 taken 9008622 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9008622 times.
9008620 if (query_block->get_optimizable_conditions(thd, &where_cond, &having_cond))
320 return true;
321
322
4/6
✓ Branch 0 taken 9008583 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9008613 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1041 times.
✓ Branch 5 taken 9008613 times.
9009663 for (Item_rollup_group_item *item : query_block->rollup_group_items) {
323
1/2
✓ Branch 0 taken 1041 times.
✗ Branch 1 not taken.
1041 rollup_group_items.push_back(item);
324 }
325
4/6
✓ Branch 0 taken 9008617 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9008593 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 348 times.
✓ Branch 5 taken 9008593 times.
9008961 for (Item_rollup_sum_switcher *item : query_block->rollup_sums) {
326
1/2
✓ Branch 0 taken 348 times.
✗ Branch 1 not taken.
348 rollup_sums.push_back(item);
327 }
328
329 9008593 set_optimized();
330
331 9008576 tables_list = query_block->leaf_tables;
332
333
2/4
✓ Branch 0 taken 9008610 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9008610 times.
9008576 if (alloc_indirection_slices()) return true;
334
335 // The base ref items from query block are assigned as JOIN's ref items
336 9008610 ref_items[REF_SLICE_ACTIVE] = query_block->base_ref_items;
337
338 /* dump_TABLE_LIST_graph(query_block, query_block->leaf_tables); */
339 /*
340 Run optimize phase for all derived tables/views used in this SELECT,
341 including those in semi-joins.
342 */
343 // if (query_block->materialized_derived_table_count) {
344 { // WL#6570
345
2/2
✓ Branch 0 taken 3976632 times.
✓ Branch 1 taken 9008569 times.
12985201 for (TABLE_LIST *tl = query_block->leaf_tables; tl; tl = tl->next_leaf) {
346 3976632 tl->access_path_for_derived = nullptr;
347
2/2
✓ Branch 0 taken 178532 times.
✓ Branch 1 taken 3798095 times.
3976632 if (tl->is_view_or_derived()) {
348
3/4
✓ Branch 0 taken 178532 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 178513 times.
178532 if (tl->optimize_derived(thd)) return true;
349
2/2
✓ Branch 0 taken 436 times.
✓ Branch 1 taken 3797661 times.
3798095 } else if (tl->is_table_function()) {
350 436 TABLE *const table = tl->table;
351
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 401 times.
436 if (!table->has_storage_handler()) {
352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (setup_tmp_table_handler(
353
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 thd, table,
354 16 query_block->active_options() | TMP_TABLE_ALL_COLUMNS))
355 return true; /* purecov: inspected */
356 }
357
358 417 table->file->stats.records = 2;
359 }
360 }
361 }
362
363
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 9008457 times.
9008569 if (thd->lex->using_hypergraph_optimizer) {
364 // The hypergraph optimizer also wants all subselect items to be optimized,
365 // so that it has cost information to attach to filter nodes.
366 112 for (Query_expression *unit = query_block->first_inner_query_expression();
367
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 112 times.
121 unit; unit = unit->next_query_expression()) {
368 // Derived tables and const subqueries are already optimized
369
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
18 if (!unit->is_optimized() &&
370
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 unit->optimize(thd, /*materialize_destination=*/nullptr,
371 /*create_iterators=*/false,
372 /*finalize_access_paths=*/false))
373 return true;
374 }
375
376 // The hypergraph optimizer does not do const tables,
377 // nor does it evaluate subqueries during optimization.
378 112 query_block->add_active_options(OPTION_NO_CONST_TABLES |
379 OPTION_NO_SUBQUERY_DURING_OPTIMIZATION);
380 }
381
382 9008577 has_lateral = false;
383
384 /* dump_TABLE_LIST_graph(query_block, query_block->leaf_tables); */
385
386
4/4
✓ Branch 0 taken 8452425 times.
✓ Branch 1 taken 551906 times.
✓ Branch 2 taken 8432523 times.
✓ Branch 3 taken 19917 times.
9004352 row_limit = ((select_distinct || !order.empty() || !group_list.empty())
387
2/2
✓ Branch 0 taken 9004352 times.
✓ Branch 1 taken 4225 times.
18012939 ? HA_POS_ERROR
388 8432523 : query_expression()->select_limit_cnt);
389 // m_select_limit is used to decide if we are likely to scan the whole table.
390 9008587 m_select_limit = query_expression()->select_limit_cnt;
391
392
2/2
✓ Branch 0 taken 177 times.
✓ Branch 1 taken 9008416 times.
9008593 if (query_expression()->first_query_block()->active_options() &
393 OPTION_FOUND_ROWS) {
394 /*
395 Calculate found rows (ie., keep counting rows even after we hit LIMIT) if
396 - LIMIT is set, and
397 - This is the outermost query block (for a UNION query, this is the
398 fake query block that contains the limit applied on the final UNION
399 evaluation).
400 */
401
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 56 times.
298 calc_found_rows = m_select_limit != HA_POS_ERROR &&
402
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 95 times.
121 (!query_expression()->is_union() ||
403
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 14 times.
26 query_block == query_expression()->fake_query_block);
404 }
405
4/4
✓ Branch 0 taken 8998284 times.
✓ Branch 1 taken 10309 times.
✓ Branch 2 taken 88 times.
✓ Branch 3 taken 8998196 times.
9008593 if (having_cond || calc_found_rows) m_select_limit = HA_POS_ERROR;
406
407
6/6
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 9008325 times.
✓ Branch 2 taken 238 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 238 times.
✓ Branch 5 taken 9008343 times.
9008593 if (query_expression()->select_limit_cnt == 0 && !calc_found_rows) {
408 238 zero_result_cause = "Zero limit";
409 238 best_rowcount = 0;
410
1/2
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
238 create_access_paths_for_zero_rows();
411 238 goto setup_subq_exit;
412 }
413
414
4/4
✓ Branch 0 taken 7750052 times.
✓ Branch 1 taken 1258291 times.
✓ Branch 2 taken 5338 times.
✓ Branch 3 taken 7744714 times.
9008343 if (where_cond || query_block->outer_join) {
415
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1263547 times.
1263575 if (optimize_cond(thd, &where_cond, &cond_equal,
416
1/2
✓ Branch 0 taken 1263575 times.
✗ Branch 1 not taken.
1263629 &query_block->top_join_list, &query_block->cond_value)) {
417 28 error = 1;
418
3/8
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
28 DBUG_PRINT("error", ("Error from optimize_cond"));
419 28 return true;
420 }
421
2/2
✓ Branch 0 taken 11323 times.
✓ Branch 1 taken 1252224 times.
1263547 if (query_block->cond_value == Item::COND_FALSE) {
422 11323 zero_result_cause = "Impossible WHERE";
423 11323 best_rowcount = 0;
424
1/2
✓ Branch 0 taken 11323 times.
✗ Branch 1 not taken.
11323 create_access_paths_for_zero_rows();
425 11323 goto setup_subq_exit;
426 }
427 }
428
2/2
✓ Branch 0 taken 10245 times.
✓ Branch 1 taken 8986693 times.
8996938 if (having_cond) {
429
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10242 times.
10245 if (optimize_cond(thd, &having_cond, &cond_equal, nullptr,
430
1/2
✓ Branch 0 taken 10245 times.
✗ Branch 1 not taken.
10245 &query_block->having_value)) {
431 3 error = 1;
432
3/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3 DBUG_PRINT("error", ("Error from optimize_cond"));
433 3 return true;
434 }
435
2/2
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 10056 times.
10242 if (query_block->having_value == Item::COND_FALSE) {
436 186 zero_result_cause = "Impossible HAVING";
437 186 best_rowcount = 0;
438
1/2
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
186 create_access_paths_for_zero_rows();
439 186 goto setup_subq_exit;
440 }
441 }
442
443
2/2
✓ Branch 0 taken 8956629 times.
✓ Branch 1 taken 40120 times.
8996749 if (thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
444
2/2
✓ Branch 0 taken 793 times.
✓ Branch 1 taken 8955836 times.
8956629 thd->lex->sql_command == SQLCOM_REPLACE_SELECT) {
445 /*
446 Statement-based replication of INSERT ... SELECT ... LIMIT and
447 REPLACE ... SELECT is safe as order of row is defined with either
448 ORDER BY or other condition. However it is too late for it have
449 an impact to our decision to switch to row- based. We can only
450 suppress warning here.
451 */
452
1/2
✓ Branch 0 taken 694 times.
✗ Branch 1 not taken.
694 if (query_block->select_limit && query_block->select_limit->fixed &&
453
6/8
✓ Branch 0 taken 694 times.
✓ Branch 1 taken 40219 times.
✓ Branch 2 taken 694 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 694 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 424 times.
✓ Branch 7 taken 40489 times.
42301 query_block->select_limit->val_int() &&
454
3/4
✓ Branch 0 taken 694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 424 times.
✓ Branch 3 taken 270 times.
694 !is_order_deterministic(&query_block->top_join_list, where_cond,
455 order.order)) {
456 424 thd->order_deterministic = false;
457 }
458 }
459
460
7/8
✓ Branch 0 taken 83698 times.
✓ Branch 1 taken 8913051 times.
✓ Branch 2 taken 83698 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 83695 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 8996746 times.
8996749 if (query_block->partitioned_table_count && prune_table_partitions()) {
461 3 error = 1;
462
3/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3 DBUG_PRINT("error", ("Error from prune_partitions"));
463 3 return true;
464 }
465
466 /*
467 Try to optimize count(*), min() and max() to const fields if
468 there is implicit grouping (aggregate functions but no
469 group_list). In this case, the result set shall only contain one
470 row.
471 */
472
6/6
✓ Branch 0 taken 1877630 times.
✓ Branch 1 taken 7119116 times.
✓ Branch 2 taken 349981 times.
✓ Branch 3 taken 1527649 times.
✓ Branch 4 taken 349580 times.
✓ Branch 5 taken 8647166 times.
9346727 if (tables_list && implicit_grouping &&
473
2/2
✓ Branch 0 taken 349580 times.
✓ Branch 1 taken 401 times.
349981 !(query_block->active_options() & OPTION_NO_CONST_TABLES)) {
474 aggregate_evaluated outcome;
475
3/4
✓ Branch 0 taken 349580 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 349568 times.
349580 if (optimize_aggregated_query(thd, query_block, *fields, where_cond,
476 &outcome)) {
477 12 error = 1;
478
3/8
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
12 DBUG_PRINT("error", ("Error from optimize_aggregated_query"));
479 12 return true;
480 }
481
4/5
✓ Branch 0 taken 323115 times.
✓ Branch 1 taken 15860 times.
✓ Branch 2 taken 6082 times.
✓ Branch 3 taken 4511 times.
✗ Branch 4 not taken.
349568 switch (outcome) {
482 323115 case AGGR_REGULAR:
483 // Query was not (fully) evaluated. Revert to regular optimization.
484 323115 break;
485 15860 case AGGR_DELAYED:
486 // Query was not (fully) evaluated. Revert to regular optimization,
487 // but indicate that storage engine supports HA_COUNT_ROWS_INSTANT.
488 15860 select_count = true;
489 15860 break;
490 6082 case AGGR_COMPLETE: {
491 // All SELECT expressions are fully evaluated
492
3/8
✓ Branch 0 taken 6082 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6082 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6082 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6082 DBUG_PRINT("info", ("Select tables optimized away"));
493 6082 zero_result_cause = "Select tables optimized away";
494 6082 tables_list = nullptr; // All tables resolved
495 6082 best_rowcount = 1;
496 6082 const_tables = tables = primary_tables = query_block->leaf_table_count;
497 AccessPath *path =
498 6082 NewFakeSingleRowAccessPath(thd, /*count_examined_rows=*/true);
499
1/2
✓ Branch 0 taken 6082 times.
✗ Branch 1 not taken.
6082 path = attach_access_paths_for_having_and_limit(path);
500 6082 m_root_access_path = path;
501 /*
502 There are no relevant conditions left from the WHERE;
503 optimize_aggregated_query() will not return AGGR_COMPLETE if there are
504 any table-independent conditions, and all other conditions have been
505 optimized away by it. Thus, remove the condition, unless we have
506 EXPLAIN (in which case we will keep it for printing).
507 */
508
2/2
✓ Branch 0 taken 5928 times.
✓ Branch 1 taken 154 times.
6082 if (!thd->lex->is_explain()) {
509 #ifndef NDEBUG
510 // Verify, to be sure.
511
2/2
✓ Branch 0 taken 3244 times.
✓ Branch 1 taken 2684 times.
5928 if (where_cond != nullptr) {
512 6488 Item *table_independent_conds = make_cond_for_table(
513
1/2
✓ Branch 0 taken 3244 times.
✗ Branch 1 not taken.
3244 thd, where_cond, PSEUDO_TABLE_BITS, table_map(0),
514 /*exclude_expensive_cond=*/true);
515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3244 times.
3244 assert(table_independent_conds == nullptr);
516 }
517 #endif
518 5928 where_cond = nullptr;
519 }
520 10593 goto setup_subq_exit;
521 }
522 4511 case AGGR_EMPTY:
523 // It was detected that the result tables are empty
524
3/8
✓ Branch 0 taken 4511 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4511 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4511 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4511 DBUG_PRINT("info", ("No matching min/max row"));
525 4511 zero_result_cause = "No matching min/max row";
526
1/2
✓ Branch 0 taken 4511 times.
✗ Branch 1 not taken.
4511 create_access_paths_for_zero_rows();
527 4511 goto setup_subq_exit;
528 }
529 }
530
2/2
✓ Branch 0 taken 7119112 times.
✓ Branch 1 taken 1867029 times.
8986141 if (tables_list == nullptr) {
531
5/8
✓ Branch 0 taken 7119120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7119122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 7119119 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
7119112 DBUG_PRINT("info", ("No tables"));
532 7119122 best_rowcount = 1;
533 7119122 error = 0;
534
3/4
✓ Branch 0 taken 7119122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 7119121 times.
7119122 if (make_tmp_tables_info()) return true;
535
1/2
✓ Branch 0 taken 7119128 times.
✗ Branch 1 not taken.
7119121 count_field_types(query_block, &tmp_table_param, *fields, false, false);
536 // Make plan visible for EXPLAIN
537
1/2
✓ Branch 0 taken 7119130 times.
✗ Branch 1 not taken.
7119128 set_plan_state(NO_TABLES);
538
1/2
✓ Branch 0 taken 7119113 times.
✗ Branch 1 not taken.
7119130 create_access_paths();
539 7119113 return false;
540 }
541 1867029 error = -1; // Error is sent to client
542
543 {
544 1867029 m_windowing_steps = false; // initialization
545 1867029 m_windows_sort = false;
546
1/2
✓ Branch 0 taken 1867067 times.
✗ Branch 1 not taken.
1867029 List_iterator<Window> li(m_windows);
547 Window *w;
548
2/2
✓ Branch 0 taken 2045 times.
✓ Branch 1 taken 1865703 times.
1867736 while ((w = li++))
549
2/2
✓ Branch 0 taken 1376 times.
✓ Branch 1 taken 669 times.
2045 if (w->needs_sorting()) {
550 1376 m_windows_sort = true;
551 1376 break;
552 }
553 }
554
555 3734124 sort_by_table = get_sort_by_table(order.order, group_list.order,
556
1/2
✓ Branch 0 taken 1867045 times.
✗ Branch 1 not taken.
1867079 query_block->leaf_tables);
557
558
8/8
✓ Branch 0 taken 631842 times.
✓ Branch 1 taken 1235203 times.
✓ Branch 2 taken 624352 times.
✓ Branch 3 taken 7490 times.
✓ Branch 4 taken 212068 times.
✓ Branch 5 taken 412284 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 1867085 times.
3321849 if ((where_cond || !group_list.empty() || !order.empty()) &&
559
3/4
✓ Branch 0 taken 1454804 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1454801 times.
1454761 substitute_gc(thd, query_block, where_cond, group_list.order,
560 order.order)) {
561 // We added hidden fields to the all_fields list, count them.
562
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 count_field_types(query_block, &tmp_table_param, query_block->fields, false,
563 false);
564 }
565 // Ensure there are no errors prior making query plan
566
3/4
✓ Branch 0 taken 1867090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1867088 times.
1867088 if (thd->is_error()) return true;
567
568
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 1866992 times.
1867088 if (thd->lex->using_hypergraph_optimizer) {
569
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 Item *where_cond_no_in2exists = remove_in2exists_conds(thd, where_cond);
570
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 Item *having_cond_no_in2exists = remove_in2exists_conds(thd, having_cond);
571
572 96 std::string trace_str;
573
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 56 times.
96 std::string *trace_ptr = thd->opt_trace.is_started() ? &trace_str : nullptr;
574
575
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 SaveCondEqualLists(cond_equal);
576
577
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 m_root_access_path = FindBestQueryPlan(thd, query_block, trace_ptr);
578
3/4
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
96 if (finalize_access_paths && m_root_access_path != nullptr) {
579
2/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 76 times.
76 if (FinalizePlanForQueryBlock(thd, query_block)) {
580 return true;
581 }
582 }
583
584 // If this query block was modified by IN-to-EXISTS conversion,
585 // the outer query block may want to undo that conversion and materialize
586 // us instead, depending on cost. (Materialization has high initial cost,
587 // but looking up in the materialized table is typically cheaper than
588 // running the entire query.) If so, we will need to plan the query again,
589 // but with all extra conditions added by IN-to-EXISTS removed, as those
590 // are specific to the values referred to by the outer query.
591 //
592 // Thus, we detect this here, and plan a second query plan. There are
593 // computations that could be shared between the two plans (e.g. join order
594 // between tables for which there is no IN-to-EXISTS-related condition),
595 // so it is somewhat wasteful, but experiments have shown that planning
596 // both at the same time quickly clutters the code with such handling;
597 // there are so many places such filters could be added (base table filters,
598 // filters after various types of joins, join conditions, post-join filters,
599 // HAVING, possibly others) that trying to plan paths both with and without
600 // them incurs complexity that is not justified by the small computational
601 // gain it would bring.
602
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 1 times.
96 if (where_cond != where_cond_no_in2exists ||
603
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 88 times.
95 having_cond != having_cond_no_in2exists) {
604
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (trace_ptr != nullptr) {
605 *trace_ptr +=
606
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 "\nPlanning an alternative with in2exists conditions removed:\n";
607 }
608 8 where_cond = where_cond_no_in2exists;
609 8 having_cond = having_cond_no_in2exists;
610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(!finalize_access_paths);
611 8 m_root_access_path_no_in2exists =
612
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 FindBestQueryPlan(thd, query_block, trace_ptr);
613 } else {
614 88 m_root_access_path_no_in2exists = nullptr;
615 }
616
617
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 if (trace != nullptr) {
618
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 Opt_trace_object trace_wrapper2(&thd->opt_trace);
619
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 Opt_trace_array join_optimizer(&thd->opt_trace, "join_optimizer");
620
621 // Split by newlines.
622
2/2
✓ Branch 0 taken 2183 times.
✓ Branch 1 taken 96 times.
2279 for (size_t pos = 0; pos < trace_str.size();) {
623 2183 size_t len = strcspn(trace_str.data() + pos, "\n");
624
1/2
✓ Branch 0 taken 2183 times.
✗ Branch 1 not taken.
2183 join_optimizer.add_utf8(trace_str.data() + pos, len);
625 2183 pos += len + 1;
626 }
627 96 }
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (m_root_access_path == nullptr) {
629 return true;
630 }
631
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 set_plan_state(PLAN_READY);
632
2/4
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
96 DEBUG_SYNC(thd, "after_join_optimize");
633 96 return false;
634 96 }
635
636 // ----------------------------------------------------------------------------
637 // All of this is never called for the hypergraph join optimizer!
638 // ----------------------------------------------------------------------------
639
640 // Set up join order and initial access paths
641
1/2
✓ Branch 0 taken 1866983 times.
✗ Branch 1 not taken.
1866992 THD_STAGE_INFO(thd, stage_statistics);
642
3/4
✓ Branch 0 taken 1866980 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 1866872 times.
1866983 if (make_join_plan()) {
643
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 98 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
108 if (thd->killed) thd->send_kill_message();
644
3/8
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 108 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
108 DBUG_PRINT("error", ("Error: JOIN::make_join_plan() failed"));
645 108 return true;
646 }
647
648 // At this stage, join_tab==NULL, JOIN_TABs are listed in order by best_ref.
649
4/6
✓ Branch 0 taken 1866815 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 1866821 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1866846 times.
✗ Branch 5 not taken.
1866872 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
650
651
2/2
✓ Branch 0 taken 50239 times.
✓ Branch 1 taken 1816664 times.
1866903 if (zero_result_cause != nullptr) { // Can be set by make_join_plan().
652
1/2
✓ Branch 0 taken 50239 times.
✗ Branch 1 not taken.
50239 create_access_paths_for_zero_rows();
653 50239 goto setup_subq_exit;
654 }
655
656
2/2
✓ Branch 0 taken 1816205 times.
✓ Branch 1 taken 459 times.
1816664 if (rollup_state == RollupState::NONE) {
657 /* Remove distinct if only const tables */
658 1816205 select_distinct &= !plan_is_const();
659 }
660
661
6/6
✓ Branch 0 taken 87134 times.
✓ Branch 1 taken 1729569 times.
✓ Branch 2 taken 82516 times.
✓ Branch 3 taken 4618 times.
✓ Branch 4 taken 80393 times.
✓ Branch 5 taken 1736310 times.
1899219 if (const_tables && !thd->locked_tables_mode &&
662
2/2
✓ Branch 0 taken 80393 times.
✓ Branch 1 taken 2123 times.
82516 !(query_block->active_options() & SELECT_NO_UNLOCK)) {
663 TABLE *ct[MAX_TABLES];
664
2/2
✓ Branch 0 taken 83123 times.
✓ Branch 1 taken 80393 times.
163516 for (uint i = 0; i < const_tables; i++) {
665 83123 ct[i] = best_ref[i]->table();
666
1/2
✓ Branch 0 taken 83123 times.
✗ Branch 1 not taken.
83123 ct[i]->file->ha_index_or_rnd_end();
667 }
668
1/2
✓ Branch 0 taken 80393 times.
✗ Branch 1 not taken.
80393 mysql_unlock_some_tables(thd, ct, const_tables);
669 }
670
4/4
✓ Branch 0 taken 630493 times.
✓ Branch 1 taken 1186210 times.
✓ Branch 2 taken 5741 times.
✓ Branch 3 taken 624752 times.
1816703 if (!where_cond && query_block->outer_join) {
671 /* Handle the case where we have an OUTER JOIN without a WHERE */
672
1/2
✓ Branch 0 taken 5741 times.
✗ Branch 1 not taken.
11482 where_cond = new Item_func_true(); // Always true
673 }
674
675 1816703 error = 0;
676 /*
677 Among the equal fields belonging to the same multiple equality
678 choose the one that is to be retrieved first and substitute
679 all references to these in where condition for a reference for
680 the selected field.
681 */
682
2/2
✓ Branch 0 taken 1191797 times.
✓ Branch 1 taken 624906 times.
1816703 if (where_cond) {
683 1191885 where_cond =
684
1/2
✓ Branch 0 taken 1191885 times.
✗ Branch 1 not taken.
1191797 substitute_for_best_equal_field(thd, where_cond, cond_equal, map2table);
685
2/4
✓ Branch 0 taken 1191888 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1191888 times.
1191885 if (thd->is_error()) {
686 error = 1;
687 DBUG_PRINT("error", ("Error from substitute_for_best_equal"));
688 return true;
689 }
690
1/2
✓ Branch 0 taken 1191890 times.
✗ Branch 1 not taken.
1191888 where_cond->update_used_tables();
691
3/6
✓ Branch 0 taken 1191888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1191881 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1191890 DBUG_EXECUTE("where",
692 print_where(thd, where_cond, "after substitute_best_equal",
693 QT_ORDINARY););
694 }
695
696 /*
697 Perform the same optimization on field evaluation for all join conditions.
698 */
699
2/2
✓ Branch 0 taken 6167448 times.
✓ Branch 1 taken 1816595 times.
7984043 for (uint i = const_tables; i < tables; ++i) {
700 6167448 JOIN_TAB *const tab = best_ref[i];
701
6/6
✓ Branch 0 taken 3779777 times.
✓ Branch 1 taken 2387740 times.
✓ Branch 2 taken 530067 times.
✓ Branch 3 taken 3249749 times.
✓ Branch 4 taken 530075 times.
✓ Branch 5 taken 5637481 times.
6167448 if (tab->position() && tab->join_cond()) {
702 1060114 tab->set_join_cond(substitute_for_best_equal_field(
703
1/2
✓ Branch 0 taken 530039 times.
✗ Branch 1 not taken.
530067 thd, tab->join_cond(), tab->cond_equal, map2table));
704
2/4
✓ Branch 0 taken 530070 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 530070 times.
530035 if (thd->is_error()) {
705 error = 1;
706 DBUG_PRINT("error", ("Error from substitute_for_best_equal"));
707 return true;
708 }
709
1/2
✓ Branch 0 taken 530079 times.
✗ Branch 1 not taken.
530070 tab->join_cond()->update_used_tables();
710
2/2
✓ Branch 0 taken 530078 times.
✓ Branch 1 taken 1 times.
530079 if (tab->join_cond())
711
1/2
✓ Branch 0 taken 529919 times.
✗ Branch 1 not taken.
530078 tab->join_cond()->walk(&Item::cast_incompatible_args,
712 enum_walk::POSTFIX, nullptr);
713 }
714 }
715
716
3/4
✓ Branch 0 taken 1816642 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1816639 times.
1816595 if (init_ref_access()) {
717 3 error = 1;
718
3/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3 DBUG_PRINT("error", ("Error from init_ref_access"));
719 3 return true;
720 }
721
722 // Update table dependencies after assigning ref access fields
723
1/2
✓ Branch 0 taken 1816635 times.
✗ Branch 1 not taken.
1816639 update_depend_map();
724
725
1/2
✓ Branch 0 taken 1816630 times.
✗ Branch 1 not taken.
1816635 THD_STAGE_INFO(thd, stage_preparing);
726
727
3/4
✓ Branch 0 taken 1816601 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2011 times.
✓ Branch 3 taken 1814590 times.
1816630 if (make_join_query_block(this, where_cond)) {
728
3/4
✓ Branch 0 taken 2011 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2009 times.
2011 if (thd->is_error()) return true;
729
730 2009 zero_result_cause = "Impossible WHERE noticed after reading const tables";
731
1/2
✓ Branch 0 taken 2009 times.
✗ Branch 1 not taken.
2009 create_access_paths_for_zero_rows();
732 2009 goto setup_subq_exit;
733 }
734
735 // Inject cast nodes into the WHERE conditions
736
2/2
✓ Branch 0 taken 1113359 times.
✓ Branch 1 taken 701231 times.
1814590 if (where_cond)
737
1/2
✓ Branch 0 taken 1113389 times.
✗ Branch 1 not taken.
1113359 where_cond->walk(&Item::cast_incompatible_args, enum_walk::POSTFIX,
738 nullptr);
739
740 1814620 error = -1; /* if goto err */
741
742
3/4
✓ Branch 0 taken 1814628 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 1814582 times.
1814620 if (optimize_distinct_group_order()) return true;
743
744
4/4
✓ Branch 0 taken 1794451 times.
✓ Branch 1 taken 20123 times.
✓ Branch 2 taken 22458 times.
✓ Branch 3 taken 1792116 times.
3609033 if ((query_block->active_options() & SELECT_NO_JOIN_CACHE) ||
745
2/2
✓ Branch 0 taken 2334 times.
✓ Branch 1 taken 1792117 times.
1794451 query_block->ftfunc_list->elements)
746 22458 no_jbuf_after = 0;
747
748 /* Perform FULLTEXT search before all regular searches */
749
7/8
✓ Branch 0 taken 2351 times.
✓ Branch 1 taken 1812216 times.
✓ Branch 2 taken 2335 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 2332 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 1814548 times.
1814574 if (query_block->has_ft_funcs() && optimize_fts_query()) return true;
750
751 /*
752 By setting child_subquery_can_materialize so late we gain the following:
753 JOIN::compare_costs_of_subquery_strategies() can test this variable to
754 know if we are have finished evaluating constant conditions, which itself
755 helps determining fanouts.
756 */
757 1814548 child_subquery_can_materialize = true;
758
759 /*
760 It's necessary to check const part of HAVING cond as
761 there is a chance that some cond parts may become
762 const items after make_join_plan() (for example
763 when Item is a reference to const table field from
764 outer join).
765 This check is performed only for those conditions
766 which do not use aggregate functions. In such case
767 temporary table may not be used and const condition
768 elements may be lost during further having
769 condition transformation in JOIN::exec.
770 */
771
8/8
✓ Branch 0 taken 8581 times.
✓ Branch 1 taken 1805967 times.
✓ Branch 2 taken 4778 times.
✓ Branch 3 taken 3803 times.
✓ Branch 4 taken 55 times.
✓ Branch 5 taken 4723 times.
✓ Branch 6 taken 55 times.
✓ Branch 7 taken 1814493 times.
1814548 if (having_cond && !having_cond->has_aggregation() && (const_tables > 0)) {
772
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 having_cond->update_used_tables();
773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 if (remove_eq_conds(thd, having_cond, &having_cond,
774
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 &query_block->having_value)) {
775 error = 1;
776 DBUG_PRINT("error", ("Error from remove_eq_conds"));
777 return true;
778 }
779
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 50 times.
55 if (query_block->having_value == Item::COND_FALSE) {
780
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
10 having_cond = new Item_func_false();
781 5 zero_result_cause =
782 "Impossible HAVING noticed after reading const tables";
783
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 create_access_paths_for_zero_rows();
784 5 goto setup_subq_exit;
785 }
786 }
787
788 // Inject cast nodes into the HAVING conditions
789
2/2
✓ Branch 0 taken 8553 times.
✓ Branch 1 taken 1805990 times.
1814543 if (having_cond)
790
1/2
✓ Branch 0 taken 8553 times.
✗ Branch 1 not taken.
8553 having_cond->walk(&Item::cast_incompatible_args, enum_walk::POSTFIX,
791 nullptr);
792
793 // Traverse the expressions and inject cast nodes to compatible data types,
794 // if needed.
795
7/12
✓ Branch 0 taken 1814478 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1814542 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8087588 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8087579 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 9902133 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8087548 times.
✓ Branch 11 taken 1814585 times.
9902145 for (Item *item : *fields) {
796
1/2
✓ Branch 0 taken 8087602 times.
✗ Branch 1 not taken.
8087588 item->walk(&Item::cast_incompatible_args, enum_walk::POSTFIX, nullptr);
797 }
798
799 // Also GROUP BY expressions, so that find_in_group_list() doesn't
800 // inadvertently fail because the SELECT list has casts that GROUP BY doesn't.
801
2/2
✓ Branch 0 taken 23563 times.
✓ Branch 1 taken 1814585 times.
1838148 for (ORDER *ord = group_list.order; ord != nullptr; ord = ord->next) {
802 23563 (*ord->item)
803
1/2
✓ Branch 0 taken 23563 times.
✗ Branch 1 not taken.
23563 ->walk(&Item::cast_incompatible_args, enum_walk::POSTFIX, nullptr);
804 }
805
806
2/2
✓ Branch 0 taken 374 times.
✓ Branch 1 taken 1814211 times.
1814585 if (rollup_state != RollupState::NONE) {
807 /*
808 Fields may have been replaced by Item_rollup_group_item, so
809 recalculate the number of fields and functions for this query block.
810 */
811
812 // JOIN::optimize_rollup() may set allow_group_via_temp_table = false,
813 // and we must not undo that.
814 374 const bool save_allow_group_via_temp_table =
815 tmp_table_param.allow_group_via_temp_table;
816
817
1/2
✓ Branch 0 taken 374 times.
✗ Branch 1 not taken.
374 count_field_types(query_block, &tmp_table_param, *fields, false, false);
818 374 tmp_table_param.allow_group_via_temp_table =
819 save_allow_group_via_temp_table;
820 }
821
822 // See if this subquery can be evaluated with subselect_indexsubquery_engine
823
3/4
✓ Branch 0 taken 1814565 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1216 times.
✓ Branch 3 taken 1813349 times.
1814585 if (const int ret = replace_index_subquery()) {
824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1216 times.
1216 if (ret == -1) {
825 // Error (e.g. allocation failed, or some condition was attempted
826 // evaluated statically and failed).
827 return true;
828 }
829
830
1/2
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
1216 create_access_paths_for_index_subquery();
831
1/2
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
1216 set_plan_state(PLAN_READY);
832 /*
833 We leave optimize() because the rest of it is only about order/group
834 which those subqueries don't have and about setting up plan which
835 we're not going to use due to different execution method.
836 */
837 1216 return false;
838 }
839
840 {
841 /*
842 If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the first
843 table (it does not make sense for other tables) then we cannot do join
844 buffering.
845 */
846
2/2
✓ Branch 0 taken 1730947 times.
✓ Branch 1 taken 82404 times.
1813349 if (!plan_is_const()) {
847 1730947 const TABLE *const first = best_ref[const_tables]->table();
848
6/6
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 1729150 times.
✓ Branch 2 taken 1563 times.
✓ Branch 3 taken 220 times.
✓ Branch 4 taken 232 times.
✓ Branch 5 taken 1730701 times.
3461645 if ((first->force_index_order && !order.empty()) ||
849
4/4
✓ Branch 0 taken 1569 times.
✓ Branch 1 taken 1729144 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 1557 times.
1730713 (first->force_index_group && !group_list.empty()))
850 232 no_jbuf_after = 0;
851 }
852
853 1813337 bool simple_sort = true;
854 1813337 Table_map_restorer deps_lateral(&deps_of_remaining_lateral_derived_tables);
855 // Check whether join cache could be used
856
2/2
✓ Branch 0 taken 6162503 times.
✓ Branch 1 taken 1813487 times.
7975990 for (uint i = const_tables; i < tables; i++) {
857 6162503 JOIN_TAB *const tab = best_ref[i];
858
2/2
✓ Branch 0 taken 2384142 times.
✓ Branch 1 taken 3778469 times.
6162503 if (!tab->position()) continue;
859
2/4
✓ Branch 0 taken 3778399 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3778399 times.
3778469 if (setup_join_buffering(tab, this, no_jbuf_after)) return true;
860
2/2
✓ Branch 0 taken 131714 times.
✓ Branch 1 taken 3646770 times.
3778399 if (tab->use_join_cache() != JOIN_CACHE::ALG_NONE) simple_sort = false;
861
3/4
✓ Branch 0 taken 2167 times.
✓ Branch 1 taken 3776330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2200 times.
3778484 assert(tab->type() != JT_FT ||
862 tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
863
6/6
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 3776414 times.
✓ Branch 2 taken 562 times.
✓ Branch 3 taken 1554 times.
✓ Branch 4 taken 562 times.
✓ Branch 5 taken 3777968 times.
3778530 if (has_lateral && get_lateral_deps(*best_ref[i]) != 0) {
864 562 deps_of_remaining_lateral_derived_tables =
865
1/2
✓ Branch 0 taken 562 times.
✗ Branch 1 not taken.
562 calculate_deps_of_remaining_lateral_derived_tables(all_table_map,
866 i + 1);
867 }
868 }
869
2/2
✓ Branch 0 taken 108430 times.
✓ Branch 1 taken 1705057 times.
1813487 if (!simple_sort) {
870 /*
871 A join buffer is used for this table. We here inform the optimizer
872 that it should not rely on rows of the first non-const table being in
873 order thanks to an index scan; indeed join buffering of the present
874 table subsequently changes the order of rows.
875 */
876 108430 simple_order = simple_group = false;
877 }
878
1/2
✓ Branch 0 taken 1813358 times.
✗ Branch 1 not taken.
1813487 }
879
880
6/6
✓ Branch 0 taken 1730983 times.
✓ Branch 1 taken 82376 times.
✓ Branch 2 taken 542026 times.
✓ Branch 3 taken 1188957 times.
✓ Branch 4 taken 542026 times.
✓ Branch 5 taken 1271333 times.
1813358 if (!plan_is_const() && !order.empty()) {
881 /*
882 Force using of tmp table if sorting by a SP or UDF function due to
883 their expensive and probably non-deterministic nature.
884 */
885
2/2
✓ Branch 0 taken 848994 times.
✓ Branch 1 taken 541976 times.
1390970 for (ORDER *tmp_order = order.order; tmp_order;
886 848944 tmp_order = tmp_order->next) {
887 848994 Item *item = *tmp_order->item;
888
3/4
✓ Branch 0 taken 848994 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 848944 times.
848994 if (item->is_expensive()) {
889 /* Force tmp table without sort */
890 50 simple_order = simple_group = false;
891 50 break;
892 }
893 }
894 }
895
896 /*
897 Check if we need to create a temporary table prior to any windowing.
898
899 (1) If there is ROLLUP, which happens before DISTINCT, windowing and ORDER
900 BY, any of those clauses needs the result of ROLLUP in a tmp table.
901
902 Rows which ROLLUP adds to the result are visible only to DISTINCT,
903 windowing and ORDER BY which we handled above. So for the rest of
904 conditions ((2), etc), we can do as if there were no ROLLUP.
905
906 (2) If all tables are constant, the query's result is guaranteed to have 0
907 or 1 row only, so all SQL clauses discussed below (DISTINCT, ORDER BY,
908 GROUP BY, windowing, SQL_BUFFER_RESULT) are useless and need no tmp
909 table.
910
911 (3) If there is GROUP BY which isn't resolved by using an index or sorting
912 the first table, we need a tmp table to compute the grouped rows.
913 GROUP BY happens before windowing; so it is a pre-windowing tmp
914 table.
915
916 (4) (5) If there is DISTINCT, or ORDER BY which isn't resolved by using an
917 index or sorting the first table, those clauses need an input tmp table.
918 If we have windowing, as those clauses are used after windowing, they can
919 use the last window's tmp table.
920
921 (6) If there are different ORDER BY and GROUP BY orders, ORDER BY needs an
922 input tmp table, so it's like (5).
923
924 (7) If the user wants us to buffer the result, we need a tmp table. But
925 windowing creates one anyway, and so does the materialization of a derived
926 table.
927
928 See also the computation of Window::m_short_circuit,
929 where we make sure to create a tmp table if the clauses above want one.
930
931 (8) If the first windowing step needs sorting, filesort() will be used; it
932 can sort one table but not a join of tables, so we need a tmp table
933 then. If GROUP BY was optimized away, the pre-windowing result is 0 or 1
934 row so doesn't need sorting.
935 */
936
937
4/4
✓ Branch 0 taken 374 times.
✓ Branch 1 taken 1812985 times.
✓ Branch 2 taken 127 times.
✓ Branch 3 taken 1813232 times.
1813733 if (rollup_state != RollupState::NONE && // (1)
938
6/6
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 287 times.
✓ Branch 3 taken 47 times.
✓ Branch 4 taken 40 times.
✓ Branch 5 taken 247 times.
374 (select_distinct || has_windows || !order.empty()))
939 127 need_tmp_before_win = true;
940
941 /*
942 If we have full-text columns involved in aggregation, we need to
943 materialize it, as the saving and loading of rows in AggregateIterator
944 does not include FTS information. If we have multiple tables, we'll
945 have a materialization (either because we're aggregating into a temporary
946 table, or because we always materialize before further operations),
947 and if we have a GROUP BY, we'll either have an aggregate-to-table
948 or a sort, which also fixes the issue. However, in the case of a single
949 table and implicit grouping, we need to force the temporary table here.
950 */
951
2/2
✓ Branch 0 taken 337076 times.
✓ Branch 1 taken 1476065 times.
1813141 if (!need_tmp_before_win && implicit_grouping &&
952
9/10
✓ Branch 0 taken 1813141 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 289567 times.
✓ Branch 3 taken 47509 times.
✓ Branch 4 taken 289672 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 88 times.
✓ Branch 7 taken 289479 times.
✓ Branch 8 taken 88 times.
✓ Branch 9 taken 1813166 times.
3916067 primary_tables - const_tables == 1 && order.empty() &&
953 289672 best_ref[const_tables]->table_ref->is_fulltext_searched()) {
954
8/14
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 88 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 86 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 174 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 88 times.
✓ Branch 13 taken 86 times.
174 for (Item *item : VisibleFields(*fields)) {
955 88 need_tmp_before_win |=
956
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 contains_function_of_type(item, Item_func::FT_FUNC);
957
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 86 times.
88 if (need_tmp_before_win) break;
958 }
959 }
960
961
2/2
✓ Branch 0 taken 1730929 times.
✓ Branch 1 taken 82352 times.
1813254 if (!plan_is_const()) // (2)
962 {
963
2/2
✓ Branch 0 taken 14341 times.
✓ Branch 1 taken 1795 times.
1747065 if ((!group_list.empty() && !simple_group) || // (3)
964
4/4
✓ Branch 0 taken 1727530 times.
✓ Branch 1 taken 1628 times.
✓ Branch 2 taken 1726486 times.
✓ Branch 3 taken 1044 times.
1729158 (!has_windows && (select_distinct || // (4)
965
4/4
✓ Branch 0 taken 541057 times.
✓ Branch 1 taken 1185419 times.
✓ Branch 2 taken 299515 times.
✓ Branch 3 taken 241542 times.
1726486 (!order.empty() && !simple_order) || // (5)
966
4/4
✓ Branch 0 taken 13968 times.
✓ Branch 1 taken 1470941 times.
✓ Branch 2 taken 13851 times.
✓ Branch 3 taken 117 times.
1484934 (!group_list.empty() && !order.empty()))) || // (6)
967
2/2
✓ Branch 0 taken 5568 times.
✓ Branch 1 taken 1480804 times.
1486420 ((query_block->active_options() & OPTION_BUFFER_RESULT) &&
968
2/2
✓ Branch 0 taken 5566 times.
✓ Branch 1 taken 2 times.
5568 !has_windows &&
969
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 5500 times.
5566 !(query_expression()->derived_table &&
970 66 query_expression()
971
8/8
✓ Branch 0 taken 16136 times.
✓ Branch 1 taken 1714817 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 1625 times.
✓ Branch 5 taken 1479199 times.
✓ Branch 6 taken 250084 times.
✓ Branch 7 taken 1480786 times.
3463448 ->derived_table->uses_materialization())) || // (7)
972
4/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 19 times.
1677 (has_windows && (primary_tables - const_tables) > 1 && // (8)
973
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
85 m_windows[0]->needs_sorting() && !group_optimized_away))
974 250084 need_tmp_before_win = true;
975 }
976
977
4/6
✓ Branch 0 taken 1813324 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 1813296 times.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
1813222 DBUG_EXECUTE("info", TEST_join(this););
978
979
2/4
✓ Branch 0 taken 1813353 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1813353 times.
1813324 if (alloc_qep(tables)) return (error = 1); /* purecov: inspected */
980
981
2/2
✓ Branch 0 taken 1730978 times.
✓ Branch 1 taken 82378 times.
1813353 if (!plan_is_const()) {
982 // Test if we can use an index instead of sorting
983
1/2
✓ Branch 0 taken 1730976 times.
✗ Branch 1 not taken.
1730978 test_skip_sort();
984
985
3/4
✓ Branch 0 taken 1730929 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1730928 times.
1730976 if (finalize_table_conditions()) return true;
986 }
987
988
3/4
✓ Branch 0 taken 1813362 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1813361 times.
1813306 if (make_join_readinfo(this, no_jbuf_after))
989 1 return true; /* purecov: inspected */
990
991
3/4
✓ Branch 0 taken 1813352 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1813351 times.
1813361 if (make_tmp_tables_info()) return true;
992
993 /*
994 If we decided to not sort after all, update the cost of the JOIN.
995 Windowing sorts are handled elsewhere
996 */
997
4/4
✓ Branch 0 taken 380682 times.
✓ Branch 1 taken 1432669 times.
✓ Branch 2 taken 22534 times.
✓ Branch 3 taken 1790817 times.
2194033 if (sort_cost > 0.0 &&
998
2/2
✓ Branch 0 taken 22534 times.
✓ Branch 1 taken 358148 times.
380682 !explain_flags.any(ESP_USING_FILESORT, ESC_WINDOWING)) {
999 22534 best_read -= sort_cost;
1000 22534 sort_cost = 0.0;
1001 }
1002
1003
1/2
✓ Branch 0 taken 1813351 times.
✗ Branch 1 not taken.
1813351 count_field_types(query_block, &tmp_table_param, *fields, false, false);
1004
1005
1/2
✓ Branch 0 taken 1813265 times.
✗ Branch 1 not taken.
1813351 create_access_paths();
1006
1007 // Creating iterators may evaluate a constant hash join condition, which may
1008 // fail:
1009
2/4
✓ Branch 0 taken 1813325 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1813325 times.
1813265 if (thd->is_error()) return true;
1010
1011 /*
1012 At this stage, we have set up an AccessPath 'plan'. Traverse the
1013 AccessPath structures and find components which may be offloaded to
1014 the engines. This process is allowed to modify the AccessPath itself.
1015 (Removing/modifying FILTERs where pushed to the engines, change JOIN*
1016 algorithms being used, modify aggregate expressions, ...).
1017 This will later affects which type of Iterator we should create. Thus no
1018 Iterators should be set up until after push_to_engines() has completed.
1019
1020 Note that when the Hypergraph optimizer is used, there is an entirely
1021 different code path to push_to_engine(). (We create the AcccesPath directly
1022 instead of converting the QEP_TABs into an AccessPath structure).
1023 In the HG case we push_to_engine() when FinalizePlanForQueryBlock()
1024 has finalized the 'plan'.
1025 */
1026
2/4
✓ Branch 0 taken 1813346 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1813346 times.
1813325 if (push_to_engines()) return true;
1027
1028 // Make plan visible for EXPLAIN
1029
1/2
✓ Branch 0 taken 1813356 times.
✗ Branch 1 not taken.
1813346 set_plan_state(PLAN_READY);
1030
1031
3/4
✓ Branch 0 taken 1808486 times.
✓ Branch 1 taken 4855 times.
✓ Branch 2 taken 1808504 times.
✗ Branch 3 not taken.
1813356 DEBUG_SYNC(thd, "after_join_optimize");
1032
1033 1813359 error = 0;
1034 1813359 return false;
1035
1036 74593 setup_subq_exit:
1037
1038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74593 times.
74593 assert(zero_result_cause != nullptr);
1039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74593 times.
74593 assert(m_root_access_path != nullptr);
1040 /*
1041 Even with zero matching rows, subqueries in the HAVING clause may
1042 need to be evaluated if there are aggregate functions in the
1043 query. If this JOIN is part of an outer query, subqueries in HAVING may
1044 be evaluated several times in total; so subquery materialization makes
1045 sense.
1046 */
1047 74593 child_subquery_can_materialize = true;
1048
1049
1/2
✓ Branch 0 taken 74593 times.
✗ Branch 1 not taken.
74593 trace_steps.end(); // because all steps are done
1050
2/4
✓ Branch 0 taken 74593 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74593 times.
✗ Branch 3 not taken.
74593 Opt_trace_object(trace, "empty_result").add_alnum("cause", zero_result_cause);
1051
1052 74593 having_for_explain = having_cond;
1053 74593 error = 0;
1054
1055
3/4
✓ Branch 0 taken 74593 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52253 times.
✓ Branch 3 taken 22340 times.
74593 if (!qep_tab && best_ref) {
1056 /*
1057 After creation of JOIN_TABs in make_join_plan(), we have shortcut due to
1058 some zero_result_cause. For simplification, if we have JOIN_TABs we
1059 want QEP_TABs too.
1060 */
1061
2/4
✓ Branch 0 taken 52253 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 52253 times.
52253 if (alloc_qep(tables)) return true; /* purecov: inspected */
1062
1/2
✓ Branch 0 taken 52253 times.
✗ Branch 1 not taken.
52253 unplug_join_tabs();
1063 }
1064
1065
1/2
✓ Branch 0 taken 74593 times.
✗ Branch 1 not taken.
74593 set_plan_state(ZERO_RESULT);
1066 74593 return false;
1067 9008663 }
1068
1069 2111 void JOIN::change_to_access_path_without_in2exists() {
1070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2111 times.
2111 if (m_root_access_path_no_in2exists != nullptr) {
1071 m_root_access_path = m_root_access_path_no_in2exists;
1072 }
1073 2111 }
1074
1075 68511 void JOIN::create_access_paths_for_zero_rows() {
1076
2/2
✓ Branch 0 taken 7460 times.
✓ Branch 1 taken 61051 times.
68511 if (send_row_on_empty_set()) {
1077 // Aggregate no rows into an aggregate row.
1078 7460 m_root_access_path =
1079 7460 NewZeroRowsAggregatedAccessPath(thd, zero_result_cause);
1080 7460 m_root_access_path =
1081 7460 attach_access_paths_for_having_and_limit(m_root_access_path);
1082 } else {
1083 // Send no row at all (so also no need to check HAVING or LIMIT).
1084 61051 m_root_access_path = NewZeroRowsAccessPath(thd, zero_result_cause);
1085 }
1086 68511 m_root_access_path =
1087 68511 attach_access_path_for_update_or_delete(m_root_access_path);
1088 68511 }
1089
1090 /**
1091 Push (parts of) the query execution down to the storage engines if they
1092 can provide faster execution of the query, or part of it.
1093
1094 The handler will inspect the QEP through the
1095 AQP (Abstract Query Plan) and extract from it whatever
1096 it might implement of pushed execution.
1097
1098 It is the responsibility of the handler to store
1099 any information it need for the later execution of
1100 pushed queries and conditions.
1101
1102 @retval false Success.
1103 @retval true Error, error code saved in member JOIN::error.
1104 */
1105 1813462 bool JOIN::push_to_engines() {
1106
1/2
✓ Branch 0 taken 1813550 times.
✗ Branch 1 not taken.
1813462 DBUG_TRACE;
1107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1813550 times.
1813550 assert(m_root_access_path != nullptr);
1108
1109
2/2
✓ Branch 0 taken 3862065 times.
✓ Branch 1 taken 1813506 times.
5675571 for (TABLE_LIST *tl = query_block->leaf_tables; tl; tl = tl->next_leaf) {
1110
1/2
✓ Branch 0 taken 3862021 times.
✗ Branch 1 not taken.
3862065 const handlerton *hton = tl->table->file->hton_supporting_engine_pushdown();
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3862021 times.
3862021 if (hton != nullptr) { // Involved an engine supporting pushdown.
1112 if (unlikely(hton->push_to_engine(thd, m_root_access_path, this))) {
1113 return true;
1114 }
1115 break; // Assume that at most a single handlerton per query support
1116 // pushdown
1117 }
1118 }
1119 1813506 return false;
1120 1813506 }
1121
1122 /**
1123 Substitute all expressions in the WHERE condition and ORDER/GROUP lists
1124 that match generated columns (GC) expressions with GC fields, if any.
1125
1126 @details This function does 3 things:
1127 1) Creates list of all GC fields that are a part of a key and the GC
1128 expression is a function. All query tables are scanned. If there's no
1129 such fields, function exits.
1130 2) By means of Item::compile() WHERE clause is transformed.
1131 @see Item_func::gc_subst_transformer() for details.
1132 3) If there's ORDER/GROUP BY clauses, this function tries to substitute
1133 expressions in these lists with GC too. It removes from the list of
1134 indexed GC all elements which index blocked by hints. This is done to
1135 reduce amount of further work. Next it goes through ORDER/GROUP BY list
1136 and matches the expression in it against GC expressions in indexed GC
1137 list. When a match is found, the expression is replaced with a new
1138 Item_field for the matched GC field. Also, this new field is added to
1139 the hidden part of all_fields list.
1140
1141 @param thd thread handle
1142 @param query_block the current select
1143 @param where_cond the WHERE condition, possibly NULL
1144 @param group_list the GROUP BY clause, possibly NULL
1145 @param order the ORDER BY clause, possibly NULL
1146
1147 @return true if the GROUP BY clause or the ORDER BY clause was
1148 changed, false otherwise
1149 */
1150
1151 1703124 bool substitute_gc(THD *thd, Query_block *query_block, Item *where_cond,
1152 ORDER *group_list, ORDER *order) {
1153 1703124 List<Field> indexed_gc;
1154 1703163 Opt_trace_context *const trace = &thd->opt_trace;
1155
1/2
✓ Branch 0 taken 1703245 times.
✗ Branch 1 not taken.
1703163 Opt_trace_object trace_wrapper(trace);
1156
1/2
✓ Branch 0 taken 1703259 times.
✗ Branch 1 not taken.
1703245 Opt_trace_object subst_gc(trace, "substitute_generated_columns");
1157
1158 // Collect all GCs that are a part of a key
1159
2/2
✓ Branch 0 taken 3766966 times.
✓ Branch 1 taken 1703388 times.
5470354 for (TABLE_LIST *tl = query_block->leaf_tables; tl; tl = tl->next_leaf) {
1160
2/2
✓ Branch 0 taken 441458 times.
✓ Branch 1 taken 3325508 times.
3766966 if (tl->table->s->keys == 0) continue;
1161
2/2
✓ Branch 0 taken 34699585 times.
✓ Branch 1 taken 3325637 times.
38025222 for (uint i = 0; i < tl->table->s->fields; i++) {
1162 34699585 Field *fld = tl->table->field[i];
1163 34699585 if (fld->is_gcol() &&
1164
2/2
✓ Branch 0 taken 21637 times.
✓ Branch 1 taken 6600 times.
28237 !(fld->part_of_key.is_clear_all() &&
1165
6/6
✓ Branch 0 taken 28237 times.
✓ Branch 1 taken 34671097 times.
✓ Branch 2 taken 3355 times.
✓ Branch 3 taken 18282 times.
✓ Branch 4 taken 8492 times.
✓ Branch 5 taken 34691046 times.
34731130 fld->part_of_prefixkey.is_clear_all()) &&
1166
3/4
✓ Branch 0 taken 10159 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8492 times.
✓ Branch 3 taken 1667 times.
9955 fld->gcol_info->expr_item->can_be_substituted_for_gc()) {
1167 // Don't check allowed keys here as conditions/group/order use
1168 // different keymaps for that.
1169
1/2
✓ Branch 0 taken 8668 times.
✗ Branch 1 not taken.
8492 indexed_gc.push_back(fld);
1170 }
1171 }
1172 }
1173 // No GC in the tables used in the query
1174
2/2
✓ Branch 0 taken 1695595 times.
✓ Branch 1 taken 7793 times.
1703388 if (indexed_gc.elements == 0) return false;
1175
1176
2/2
✓ Branch 0 taken 7513 times.
✓ Branch 1 taken 280 times.
7793 if (where_cond) {
1177 // Item_func::compile will dereference this pointer, provide valid value.
1178 7513 uchar i, *dummy = &i;
1179
1/2
✓ Branch 0 taken 7513 times.
✗ Branch 1 not taken.
7513 if (where_cond->compile(&Item::gc_subst_analyzer, &dummy,
1180 &Item::gc_subst_transformer,
1181
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7511 times.
7513 pointer_cast<uchar *>(&indexed_gc)) == nullptr)
1182 2 return true;
1183
1/2
✓ Branch 0 taken 7511 times.
✗ Branch 1 not taken.
7511 subst_gc.add("resulting_condition", where_cond);
1184 }
1185
1186 // An error occur during substitution. Let caller handle it.
1187
2/4
✓ Branch 0 taken 7687 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7687 times.
7791 if (thd->is_error()) return false;
1188
1189
4/4
✓ Branch 0 taken 7651 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 7334 times.
✓ Branch 3 taken 317 times.
7687 if (!(group_list || order)) return false;
1190 // Filter out GCs that do not have index usable for GROUP/ORDER
1191 Field *gc;
1192
1/2
✓ Branch 0 taken 353 times.
✗ Branch 1 not taken.
353 List_iterator<Field> li(indexed_gc);
1193
1194
2/2
✓ Branch 0 taken 531 times.
✓ Branch 1 taken 353 times.
884 while ((gc = li++)) {
1195 531 Key_map tkm = gc->part_of_key;
1196
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 422 times.
953 tkm.intersect(group_list ? gc->table->keys_in_use_for_group_by
1197 422 : gc->table->keys_in_use_for_order_by);
1198
3/4
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 401 times.
✓ Branch 2 taken 130 times.
✗ Branch 3 not taken.
531 if (tkm.is_clear_all()) li.remove();
1199 }
1200
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 234 times.
353 if (!indexed_gc.elements) return false;
1201
1202 // Index could be used for ORDER only if there is no GROUP
1203
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 198 times.
234 ORDER *list = group_list ? group_list : order;
1204 234 bool changed = false;
1205
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 234 times.
640 for (ORDER *ord = list; ord; ord = ord->next) {
1206 406 li.rewind();
1207
3/4
✓ Branch 0 taken 406 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 393 times.
✓ Branch 3 taken 13 times.
406 if (!(*ord->item)->can_be_substituted_for_gc()) continue;
1208
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 12 times.
25 while ((gc = li++)) {
1209 Item_field *const field =
1210
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 get_gc_for_expr(*ord->item, gc, gc->result_type());
1211
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
13 if (field != nullptr) {
1212 1 changed = true;
1213 /* Add new field to field list. */
1214
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 Item **new_field = query_block->add_hidden_item(field);
1215
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->change_item_tree(ord->item, *new_field);
1216 1 query_block->hidden_items_from_optimization++;
1217 1 break;
1218 }
1219 }
1220 }
1221 // An error occur during substitution. Let caller handle it.
1222
2/4
✓ Branch 0 taken 234 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 234 times.
234 if (thd->is_error()) return false;
1223
1224
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 233 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 234 times.
234 if (changed && trace->is_started()) {
1225 String str;
1226 Query_block::print_order(
1227 thd, &str, list,
1228 enum_query_type(QT_TO_SYSTEM_CHARSET | QT_SHOW_SELECT_NUMBER |
1229 QT_NO_DEFAULT_DB));
1230 subst_gc.add_utf8(group_list ? "resulting_GROUP_BY" : "resulting_ORDER_BY",
1231 str.ptr(), str.length());
1232 }
1233 234 return changed;
1234 1703284 }
1235
1236 /**
1237 Sets the plan's state of the JOIN. This is always the final step of
1238 optimization; starting from this call, we expose the plan to other
1239 connections (via EXPLAIN CONNECTION) so the plan has to be final.
1240 keyread_optim is set here.
1241 */
1242 18016937 void JOIN::set_plan_state(enum_plan_state plan_state_arg) {
1243 // A plan should not change to another plan:
1244
3/4
✓ Branch 0 taken 9008361 times.
✓ Branch 1 taken 9008576 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9008361 times.
18016937 assert(plan_state_arg == NO_PLAN || plan_state == NO_PLAN);
1245
4/4
✓ Branch 0 taken 9008709 times.
✓ Branch 1 taken 9008228 times.
✓ Branch 2 taken 9008346 times.
✓ Branch 3 taken 363 times.
18016937 if (plan_state == NO_PLAN && plan_state_arg != NO_PLAN) {
1246
2/2
✓ Branch 0 taken 1866801 times.
✓ Branch 1 taken 7141545 times.
9008346 if (qep_tab != nullptr) {
1247 /*
1248 We want to cover primary tables, tmp tables. Note that
1249 make_tmp_tables_info() may have added a sort to the first non-const
1250 primary table, so it's important to do this assignment after
1251 make_tmp_tables_info().
1252 */
1253
2/2
✓ Branch 0 taken 6264750 times.
✓ Branch 1 taken 1866819 times.
8131569 for (uint i = const_tables; i < tables; ++i) {
1254 6264750 qep_tab[i].set_condition_optim();
1255 6264757 qep_tab[i].set_keyread_optim();
1256 }
1257 }
1258 }
1259
1260
2/2
✓ Branch 0 taken 17981642 times.
✓ Branch 1 taken 35307 times.
18016955 DEBUG_SYNC(thd, "before_set_plan");
1261
1262 // If SQLCOM_END, no thread is explaining our statement anymore.
1263 18017018 const bool need_lock = thd->query_plan.get_command() != SQLCOM_END;
1264
1265
2/2
✓ Branch 0 taken 9099896 times.
✓ Branch 1 taken 8917085 times.
18016981 if (need_lock) thd->lock_query_plan();
1266 18016947 plan_state = plan_state_arg;
1267
2/2
✓ Branch 0 taken 9099869 times.
✓ Branch 1 taken 8917078 times.
18016947 if (need_lock) thd->unlock_query_plan();
1268 18016993 }
1269
1270 1866701 bool JOIN::alloc_qep(uint n) {
1271 static_assert(MAX_TABLES <= INT_MAX8, "plan_idx needs to be wide enough.");
1272
1273
3/6
✓ Branch 0 taken 1866708 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1866719 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1866762 times.
✗ Branch 5 not taken.
1866701 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
1274
1275 1866767 qep_tab = new (thd->mem_root)
1276
4/6
✓ Branch 0 taken 1866767 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1866773 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8271278 times.
✓ Branch 5 taken 1866701 times.
12004728 QEP_TAB[n + 1]; // The last one holds only the final op_type.
1277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1866700 times.
1866700 if (!qep_tab) return true; /* purecov: inspected */
1278
2/2
✓ Branch 0 taken 6405145 times.
✓ Branch 1 taken 1866696 times.
8271841 for (uint i = 0; i < n; ++i) qep_tab[i].init(best_ref[i]);
1279 1866696 return false;
1280 }
1281
1282 6405120 void QEP_TAB::init(JOIN_TAB *jt) {
1283 6405120 jt->share_qs(this);
1284 6405181 set_table(table()); // to update table()->reginfo.qep_tab
1285 6405117 table_ref = jt->table_ref;
1286 6405117 }
1287
1288 /// @returns semijoin strategy for this table.
1289 155937 uint QEP_TAB::get_sj_strategy() const {
1290
2/2
✓ Branch 0 taken 126812 times.
✓ Branch 1 taken 29125 times.
155937 if (first_sj_inner() == NO_PLAN_IDX) return SJ_OPT_NONE;
1291 29125 const uint s = join()->qep_tab[first_sj_inner()].position()->sj_strategy;
1292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29125 times.
29125 assert(s != SJ_OPT_NONE);
1293 29125 return s;
1294 }
1295
1296 /**
1297 Return the index used for a table in a QEP
1298
1299 The various access methods have different places where the index/key
1300 number is stored, so this function is needed to return the correct value.
1301
1302 @returns index number, or MAX_KEY if not applicable.
1303
1304 JT_SYSTEM and JT_ALL does not use an index, and will always return MAX_KEY.
1305
1306 JT_INDEX_MERGE supports more than one index. Hence MAX_KEY is returned and
1307 a further inspection is needed.
1308 */
1309 5028 uint QEP_TAB::effective_index() const {
1310
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
✓ Branch 2 taken 917 times.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 337 times.
✓ Branch 5 taken 3124 times.
5028 switch (type()) {
1311 case JT_SYSTEM:
1312 assert(ref().key == -1);
1313 return MAX_KEY;
1314
1315 627 case JT_CONST:
1316 case JT_EQ_REF:
1317 case JT_REF_OR_NULL:
1318 case JT_REF:
1319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 assert(ref().key != -1);
1320 627 return uint(ref().key);
1321
1322 917 case JT_INDEX_SCAN:
1323 case JT_FT:
1324 917 return index();
1325
1326 23 case JT_INDEX_MERGE:
1327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 assert(used_index(range_scan()) == MAX_KEY);
1328 23 return MAX_KEY;
1329
1330 337 case JT_RANGE:
1331 337 return used_index(range_scan());
1332
1333 3124 case JT_ALL:
1334 default:
1335 // @todo Check why JT_UNKNOWN is a valid value here.
1336
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3124 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3124 assert(type() == JT_ALL || type() == JT_UNKNOWN);
1337 3124 return MAX_KEY;
1338 }
1339 }
1340
1341 17312008 uint JOIN_TAB::get_sj_strategy() const {
1342
2/2
✓ Branch 0 taken 17105880 times.
✓ Branch 1 taken 206299 times.
17312008 if (first_sj_inner() == NO_PLAN_IDX) return SJ_OPT_NONE;
1343
3/6
✓ Branch 0 taken 206356 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 206356 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 206356 times.
✗ Branch 5 not taken.
206299 ASSERT_BEST_REF_IN_JOIN_ORDER(join());
1344 206356 JOIN_TAB *tab = join()->best_ref[first_sj_inner()];
1345 206356 uint s = tab->position()->sj_strategy;
1346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 206356 times.
206356 assert(s != SJ_OPT_NONE);
1347 206356 return s;
1348 }
1349
1350 1814531 int JOIN::replace_index_subquery() {
1351
1/2
✓ Branch 0 taken 1814570 times.
✗ Branch 1 not taken.
1814531 DBUG_TRACE;
1352
3/6
✓ Branch 0 taken 1814570 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1814570 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1814570 times.
✗ Branch 5 not taken.
1814570 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
1353
1354 1814570 if (!group_list.empty() ||
1355
2/2
✓ Branch 0 taken 95557 times.
✓ Branch 1 taken 1702874 times.
1798430 !(query_expression()->item &&
1356
3/4
✓ Branch 0 taken 95557 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10897 times.
✓ Branch 3 taken 84660 times.
95557 query_expression()->item->substype() == Item_subselect::IN_SUBS) ||
1357
10/10
✓ Branch 0 taken 1798430 times.
✓ Branch 1 taken 16141 times.
✓ Branch 2 taken 7555 times.
✓ Branch 3 taken 3342 times.
✓ Branch 4 taken 5963 times.
✓ Branch 5 taken 1592 times.
✓ Branch 6 taken 112 times.
✓ Branch 7 taken 5815 times.
✓ Branch 8 taken 1808745 times.
✓ Branch 9 taken 5791 times.
3613002 primary_tables != 1 || !where_cond || query_expression()->is_union())
1358 1808745 return 0;
1359
1360 // Guaranteed by remove_redundant_subquery_clauses():
1361
2/4
✓ Branch 0 taken 5815 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5815 times.
✗ Branch 3 not taken.
5791 assert(order.empty() && !select_distinct);
1362
1363 Item_in_subselect *const in_subs =
1364 5815 static_cast<Item_in_subselect *>(query_expression()->item);
1365 5815 bool found_engine = false;
1366
1367 5815 JOIN_TAB *const first_join_tab = best_ref[0];
1368
1369
2/2
✓ Branch 0 taken 5451 times.
✓ Branch 1 taken 364 times.
5815 if (in_subs->strategy == Subquery_strategy::SUBQ_MATERIALIZATION) {
1370 // We cannot have two engines at the same time
1371
4/6
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 5387 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
✓ Branch 4 taken 5451 times.
✗ Branch 5 not taken.
5515 } else if (first_join_tab->table_ref->is_view_or_derived() &&
1372 64 first_join_tab->table_ref->derived_query_expression()
1373 64 ->is_recursive()) {
1374 // The index subquery engine, which runs the derived table machinery
1375 // from the old executor, is not capable of materializing a WITH RECURSIVE
1376 // query from the iterator executor. Thus, be conservative here, so that the
1377 // case never happens.
1378
2/2
✓ Branch 0 taken 3661 times.
✓ Branch 1 taken 1790 times.
5451 } else if (having_cond == nullptr) {
1379 3661 const join_type type = first_join_tab->type();
1380
6/6
✓ Branch 0 taken 3305 times.
✓ Branch 1 taken 356 times.
✓ Branch 2 taken 622 times.
✓ Branch 3 taken 2683 times.
✓ Branch 4 taken 953 times.
✓ Branch 5 taken 2708 times.
4639 if ((type == JT_EQ_REF || type == JT_REF) &&
1381
2/2
✓ Branch 0 taken 953 times.
✓ Branch 1 taken 25 times.
978 first_join_tab->ref().items[0]->item_name.ptr() == in_left_expr_name) {
1382 953 found_engine = true;
1383 }
1384 1790 } else if (first_join_tab->type() == JT_REF_OR_NULL &&
1385
2/2
✓ Branch 0 taken 263 times.
✓ Branch 1 taken 27 times.
290 first_join_tab->ref().items[0]->item_name.ptr() ==
1386
4/4
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 1500 times.
✓ Branch 2 taken 263 times.
✓ Branch 3 taken 1527 times.
2080 in_left_expr_name &&
1387
2/4
✓ Branch 0 taken 263 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 263 times.
✗ Branch 3 not taken.
263 having_cond->created_by_in2exists()) {
1388 263 found_engine = true;
1389 }
1390
1391
2/2
✓ Branch 0 taken 4599 times.
✓ Branch 1 taken 1216 times.
5815 if (!found_engine) return 0;
1392
1393 /* Remove redundant predicates and cache constant expressions */
1394
2/4
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1216 times.
1216 if (finalize_table_conditions()) return -1;
1395
1396
2/4
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1216 times.
1216 if (alloc_qep(tables)) return -1; /* purecov: inspected */
1397
1/2
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
1216 unplug_join_tabs();
1398
1399 1216 error = 0;
1400 1216 QEP_TAB *const first_qep_tab = &qep_tab[0];
1401
1402
2/2
✓ Branch 0 taken 811 times.
✓ Branch 1 taken 405 times.
1216 if (first_qep_tab->table()->covering_keys.is_set(first_qep_tab->ref().key)) {
1403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 811 times.
811 assert(!first_qep_tab->table()->no_keyread);
1404
1/2
✓ Branch 0 taken 811 times.
✗ Branch 1 not taken.
811 first_qep_tab->table()->set_keyread(true);
1405 }
1406
1407 subselect_indexsubquery_engine *engine =
1408 1216 new (thd->mem_root) subselect_indexsubquery_engine(
1409 1216 first_qep_tab->table(), first_qep_tab->table_ref,
1410 1216 first_qep_tab->ref(), first_qep_tab->type(),
1411 1216 down_cast<Item_in_subselect *>(query_expression()->item),
1412
1/2
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
1216 first_qep_tab->condition(), having_cond);
1413 1216 query_expression()->item->set_indexsubquery_engine(engine);
1414 1216 return 1;
1415 1814560 }
1416
1417 1814517 bool JOIN::optimize_distinct_group_order() {
1418
1/2
✓ Branch 0 taken 1814624 times.
✗ Branch 1 not taken.
1814517 DBUG_TRACE;
1419
4/6
✓ Branch 0 taken 1814624 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1814590 times.
✓ Branch 3 taken 34 times.
✓ Branch 4 taken 1814595 times.
✗ Branch 5 not taken.
1814624 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
1420 1814595 const bool windowing = m_windows.elements > 0;
1421
2/2
✓ Branch 0 taken 1795870 times.
✓ Branch 1 taken 14567 times.
1810437 const bool may_trace = select_distinct || !group_list.empty() ||
1422
6/6
✓ Branch 0 taken 1810437 times.
✓ Branch 1 taken 4158 times.
✓ Branch 2 taken 1251823 times.
✓ Branch 3 taken 544048 times.
✓ Branch 4 taken 1250346 times.
✓ Branch 5 taken 1477 times.
4875378 !order.empty() || windowing ||
1423
2/2
✓ Branch 0 taken 337051 times.
✓ Branch 1 taken 913295 times.
1250346 tmp_table_param.sum_func_count;
1424 1814596 Opt_trace_context *const trace = &thd->opt_trace;
1425
1/2
✓ Branch 0 taken 1814596 times.
✗ Branch 1 not taken.
1814596 Opt_trace_disable_I_S trace_disabled(trace, !may_trace);
1426
1/2
✓ Branch 0 taken 1814611 times.
✗ Branch 1 not taken.
1814596 Opt_trace_object wrapper(trace);
1427
1/2
✓ Branch 0 taken 1814617 times.
✗ Branch 1 not taken.
1814611 Opt_trace_object trace_opt(trace, "optimizing_distinct_group_by_order_by");
1428 /* Optimize distinct away if possible */
1429 {
1430 1814617 ORDER *org_order = order.order;
1431 1814574 order = ORDER_with_src(
1432
1/2
✓ Branch 0 taken 1814574 times.
✗ Branch 1 not taken.
1814617 remove_const(order.order, where_cond, rollup_state == RollupState::NONE,
1433 &simple_order, false),
1434 order.src);
1435
3/4
✓ Branch 0 taken 1814605 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 1814568 times.
1814592 if (thd->is_error()) {
1436 37 error = 1;
1437
3/8
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 37 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
37 DBUG_PRINT("error", ("Error from remove_const"));
1438 37 return true;
1439 }
1440
1441 /*
1442 If we are using ORDER BY NULL or ORDER BY const_expression,
1443 return result in any order (even if we are using a GROUP BY)
1444 */
1445
6/6
✓ Branch 0 taken 1269730 times.
✓ Branch 1 taken 544754 times.
✓ Branch 2 taken 3634 times.
✓ Branch 3 taken 1266096 times.
✓ Branch 4 taken 3634 times.
✓ Branch 5 taken 1810850 times.
1814568 if (order.empty() && org_order) skip_sort_order = true;
1446 }
1447 /*
1448 Check if we can optimize away GROUP BY/DISTINCT.
1449 We can do that if there are no aggregate functions, the
1450 fields in DISTINCT clause (if present) and/or columns in GROUP BY
1451 (if present) contain direct references to all key parts of
1452 an unique index (in whatever order) and if the key parts of the
1453 unique index cannot contain NULLs.
1454 Note that the unique keys for DISTINCT and GROUP BY should not
1455 be the same (as long as they are unique).
1456
1457 The FROM clause must contain a single non-constant table.
1458
1459 @todo Apart from the LIS test, every condition depends only on facts
1460 which can be known in Query_block::prepare(), possibly this block should
1461 move there.
1462 */
1463
1464 1814484 JOIN_TAB *const tab = best_ref[const_tables];
1465
1466
4/4
✓ Branch 0 taken 1273932 times.
✓ Branch 1 taken 12874 times.
✓ Branch 2 taken 3120 times.
✓ Branch 3 taken 1270812 times.
3101290 if (plan_is_single_table() && (!group_list.empty() || select_distinct) &&
1467
8/8
✓ Branch 0 taken 1286806 times.
✓ Branch 1 taken 527685 times.
✓ Branch 2 taken 5747 times.
✓ Branch 3 taken 10247 times.
✓ Branch 4 taken 319 times.
✓ Branch 5 taken 5428 times.
✓ Branch 6 taken 5572 times.
✓ Branch 7 taken 1808910 times.
3107354 !tmp_table_param.sum_func_count &&
1468 5747 (!tab->range_scan() ||
1469
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 166 times.
319 tab->range_scan()->type != AccessPath::GROUP_INDEX_SKIP_SCAN)) {
1470
6/6
✓ Branch 0 taken 2529 times.
✓ Branch 1 taken 3043 times.
✓ Branch 2 taken 2427 times.
✓ Branch 3 taken 102 times.
✓ Branch 4 taken 273 times.
✓ Branch 5 taken 5299 times.
7999 if (!group_list.empty() && rollup_state == RollupState::NONE &&
1471
2/2
✓ Branch 0 taken 273 times.
✓ Branch 1 taken 2154 times.
2427 list_contains_unique_index(tab, find_field_in_order_list,
1472
1/2
✓ Branch 0 taken 2427 times.
✗ Branch 1 not taken.
2427 (void *)group_list.order)) {
1473 /*
1474 We have found that grouping can be removed since groups correspond to
1475 only one row anyway.
1476 */
1477 273 group_list.clean();
1478 273 grouped = false;
1479 }
1480
4/4
✓ Branch 0 taken 3106 times.
✓ Branch 1 taken 2466 times.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 5381 times.
8678 if (select_distinct &&
1481
3/4
✓ Branch 0 taken 3106 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 2915 times.
3106 list_contains_unique_index(tab, find_field_in_item_list, fields)) {
1482 191 select_distinct = false;
1483
1/2
✓ Branch 0 taken 191 times.
✗ Branch 1 not taken.
191 trace_opt.add("distinct_is_on_unique", true)
1484
1/2
✓ Branch 0 taken 191 times.
✗ Branch 1 not taken.
191 .add("removed_distinct", true);
1485 }
1486 }
1487
4/4
✓ Branch 0 taken 1462947 times.
✓ Branch 1 taken 337057 times.
✓ Branch 2 taken 1461362 times.
✓ Branch 3 taken 1585 times.
3614486 if (!(!group_list.empty() || tmp_table_param.sum_func_count || windowing) &&
1488
8/8
✓ Branch 0 taken 1800004 times.
✓ Branch 1 taken 14486 times.
✓ Branch 2 taken 3794 times.
✓ Branch 3 taken 1457568 times.
✓ Branch 4 taken 2947 times.
✓ Branch 5 taken 847 times.
✓ Branch 6 taken 2947 times.
✓ Branch 7 taken 1811543 times.
3617441 select_distinct && plan_is_single_table() &&
1489
1/2
✓ Branch 0 taken 2947 times.
✗ Branch 1 not taken.
2947 rollup_state == RollupState::NONE) {
1490 2947 int order_idx = -1, group_idx = -1;
1491 /*
1492 We are only using one table. In this case we change DISTINCT to a
1493 GROUP BY query if:
1494 - The GROUP BY can be done through indexes (no sort) and the ORDER
1495 BY only uses selected fields.
1496 (In this case we can later optimize away GROUP BY and ORDER BY)
1497 - We are scanning the whole table without LIMIT
1498 This can happen if:
1499 - We are using CALC_FOUND_ROWS
1500 - We are using an ORDER BY that can't be optimized away.
1501 - Selected expressions are not set functions (those cannot be put
1502 into GROUP BY).
1503
1504 We don't want to use this optimization when we are using LIMIT
1505 because in this case we can just create a temporary table that
1506 holds LIMIT rows and stop when this table is full.
1507 */
1508
2/2
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 2704 times.
2947 if (!order.empty()) {
1509 486 skip_sort_order = test_if_skip_sort_order(
1510 243 tab, order, m_select_limit,
1511 true, // no_changes
1512
1/2
✓ Branch 0 taken 243 times.
✗ Branch 1 not taken.
243 &tab->table()->keys_in_use_for_order_by, &order_idx);
1513
1/2
✓ Branch 0 taken 243 times.
✗ Branch 1 not taken.
243 count_field_types(query_block, &tmp_table_param, *fields, false, false);
1514 }
1515 ORDER *o;
1516 bool all_order_fields_used;
1517 /*
1518 There is possibility where the REF_SLICE_ACTIVE points to
1519 freed-up Items like in case of non-first row of a UPDATE
1520 trigger. Re-load the Items before using the slice.
1521 */
1522
1/2
✓ Branch 0 taken 2947 times.
✗ Branch 1 not taken.
2947 refresh_base_slice();
1523
2/2
✓ Branch 0 taken 2918 times.
✓ Branch 1 taken 29 times.
2947 if ((o = create_order_from_distinct(
1524
1/2
✓ Branch 0 taken 2947 times.
✗ Branch 1 not taken.
2947 thd, ref_items[REF_SLICE_ACTIVE], order.order, fields,
1525 /*skip_aggregates=*/true,
1526 /*convert_bit_fields_to_long=*/true, &all_order_fields_used))) {
1527 2918 group_list = ORDER_with_src(o, ESC_DISTINCT);
1528 const bool skip_group =
1529
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 2881 times.
2955 skip_sort_order &&
1530
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 10 times.
37 test_if_skip_sort_order(tab, group_list, m_select_limit,
1531 true, // no_changes
1532
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 &tab->table()->keys_in_use_for_group_by,
1533 2918 &group_idx);
1534
1/2
✓ Branch 0 taken 2918 times.
✗ Branch 1 not taken.
2918 count_field_types(query_block, &tmp_table_param, *fields, false, false);
1535 // ORDER BY and GROUP BY are using different indexes, can't skip sorting
1536
6/6
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 2891 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 19 times.
2918 if (group_idx >= 0 && order_idx >= 0 && group_idx != order_idx)
1537 2 skip_sort_order = false;
1538
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 25 times.
27 if ((skip_group && all_order_fields_used) ||
1539
6/6
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 2891 times.
✓ Branch 2 taken 94 times.
✓ Branch 3 taken 2799 times.
✓ Branch 4 taken 2853 times.
✓ Branch 5 taken 65 times.
3039 m_select_limit == HA_POS_ERROR ||
1540
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 4 times.
94 (!order.empty() && !skip_sort_order)) {
1541 /* Change DISTINCT to GROUP BY */
1542 2853 select_distinct = false;
1543 /*
1544 group_list was created with ORDER BY clause as prefix and
1545 replaces it. So it must respect ordering. If there is no
1546 ORDER BY, GROUP BY need not have to provide order.
1547 */
1548
2/2
✓ Branch 0 taken 2616 times.
✓ Branch 1 taken 237 times.
2853 if (order.empty()) {
1549
2/2
✓ Branch 0 taken 3731 times.
✓ Branch 1 taken 2616 times.
6347 for (ORDER *group = group_list.order; group; group = group->next)
1550 3731 group->direction = ORDER_NOT_RELEVANT;
1551 }
1552
8/8
✓ Branch 0 taken 2810 times.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 2779 times.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 19 times.
✓ Branch 7 taken 2834 times.
2853 if (all_order_fields_used && skip_sort_order && !order.empty()) {
1553 /*
1554 Force MySQL to read the table in sorted order to get result in
1555 ORDER BY order.
1556 */
1557 19 tmp_table_param.allow_group_via_temp_table = false;
1558 }
1559 2853 grouped = true; // For end_write_group
1560
1/2
✓ Branch 0 taken 2853 times.
✗ Branch 1 not taken.
2853 trace_opt.add("changed_distinct_to_group_by", true);
1561 } else
1562 65 group_list.clean();
1563
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 } else if (thd->is_fatal_error()) // End of memory
1564 return true;
1565 }
1566 1814490 simple_group = false;
1567
1568 1814490 ORDER *old_group_list = group_list.order;
1569 1814563 group_list = ORDER_with_src(
1570 remove_const(group_list.order, where_cond,
1571
1/2
✓ Branch 0 taken 1814563 times.
✗ Branch 1 not taken.
1814490 rollup_state == RollupState::NONE, &simple_group, true),
1572 group_list.src);
1573
1574
3/4
✓ Branch 0 taken 1814565 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 1814556 times.
1814585 if (thd->is_error()) {
1575 9 error = 1;
1576
3/8
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
9 DBUG_PRINT("error", ("Error from remove_const"));
1577 9 return true;
1578 }
1579
6/6
✓ Branch 0 taken 17342 times.
✓ Branch 1 taken 1797214 times.
✓ Branch 2 taken 1202 times.
✓ Branch 3 taken 16140 times.
✓ Branch 4 taken 1202 times.
✓ Branch 5 taken 1813354 times.
1814556 if (old_group_list && group_list.empty()) select_distinct = false;
1580
1581
6/6
✓ Branch 0 taken 1798418 times.
✓ Branch 1 taken 16137 times.
✓ Branch 2 taken 1202 times.
✓ Branch 3 taken 1797216 times.
✓ Branch 4 taken 1202 times.
✓ Branch 5 taken 1813353 times.
1814556 if (group_list.empty() && grouped) {
1582 1202 order.clean(); // The output has only one row
1583 1202 simple_order = true;
1584 1202 select_distinct = false; // No need in distinct for 1 row
1585 1202 group_optimized_away = true;
1586 }
1587
1588
1/2
✓ Branch 0 taken 1814497 times.
✗ Branch 1 not taken.
1814555 calc_group_buffer(this, group_list.order);
1589 1814497 send_group_parts = tmp_table_param.group_parts; /* Save org parts */
1590
1591 /*
1592 If ORDER BY is a prefix of GROUP BY and if windowing or ROLLUP
1593 doesn't change this order, ORDER BY can be removed and we can
1594 enforce GROUP BY to provide order.
1595 Also true if the result is one row.
1596 */
1597
3/4
✓ Branch 0 taken 1814493 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1271334 times.
✓ Branch 3 taken 1209 times.
3087040 if ((test_if_subpart(group_list.order, order.order) && !m_windows_sort &&
1598
8/8
✓ Branch 0 taken 1272543 times.
✓ Branch 1 taken 541950 times.
✓ Branch 2 taken 309 times.
✓ Branch 3 taken 1271025 times.
✓ Branch 4 taken 542450 times.
✓ Branch 5 taken 1065 times.
✓ Branch 6 taken 1271038 times.
✓ Branch 7 taken 543502 times.
4171792 query_block->olap != ROLLUP_TYPE) ||
1599
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 542448 times.
1085918 (group_list.empty() && tmp_table_param.sum_func_count)) {
1600
2/2
✓ Branch 0 taken 2720 times.
✓ Branch 1 taken 1268328 times.
1271038 if (!order.empty()) {
1601 2720 order.clean();
1602
1/2
✓ Branch 0 taken 2720 times.
✗ Branch 1 not taken.
2720 trace_opt.add("removed_order_by", true);
1603 }
1604
3/4
✓ Branch 0 taken 1270972 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 666 times.
✓ Branch 3 taken 1270306 times.
1271048 if (is_indexed_agg_distinct(this, nullptr)) streaming_aggregation = false;
1605 }
1606
1607 1814474 return false;
1608 1814520 }
1609
1610 1730913 void JOIN::test_skip_sort() {
1611
1/2
✓ Branch 0 taken 1730983 times.
✗ Branch 1 not taken.
1730913 DBUG_TRACE;
1612
3/6
✓ Branch 0 taken 1730983 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1730983 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1730984 times.
✗ Branch 5 not taken.
1730983 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
1613 1730984 JOIN_TAB *const tab = best_ref[const_tables];
1614
1615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1730984 times.
1730984 assert(m_ordered_index_usage == ORDERED_INDEX_VOID);
1616
1617
2/2
✓ Branch 0 taken 16136 times.
✓ Branch 1 taken 1714843 times.
1730984 if (!group_list.empty()) // GROUP BY honoured first
1618 // (DISTINCT was rewritten to GROUP BY if skippable)
1619 {
1620 /*
1621 When there is SQL_BIG_RESULT or a JSON aggregation function,
1622 do not sort using index for GROUP BY, and thus force sorting on disk
1623 unless a group min-max optimization is going to be used as it is applied
1624 now only for one table queries with covering indexes.
1625 */
1626
8/8
✓ Branch 0 taken 16065 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 16005 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 129 times.
✓ Branch 6 taken 16007 times.
✓ Branch 7 taken 129 times.
16269 if (!(query_block->active_options() & SELECT_BIG_RESULT || with_json_agg) ||
1627 131 (tab->range_scan() &&
1628
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 tab->range_scan()->type == AccessPath::GROUP_INDEX_SKIP_SCAN)) {
1629
2/2
✓ Branch 0 taken 14231 times.
✓ Branch 1 taken 1776 times.
16007 if (simple_group && // GROUP BY is possibly skippable
1630
2/2
✓ Branch 0 taken 14110 times.
✓ Branch 1 taken 121 times.
14231 !select_distinct) // .. if not preceded by a DISTINCT
1631 {
1632 /*
1633 Calculate a possible 'limit' of table rows for 'GROUP BY':
1634 A specified 'LIMIT' is relative to the final resultset.
1635 'need_tmp' implies that there will be more postprocessing
1636 so the specified 'limit' should not be enforced yet.
1637 */
1638 14110 const ha_rows limit =
1639
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 13704 times.
14110 (need_tmp_before_win ? HA_POS_ERROR : m_select_limit);
1640 int dummy;
1641
1642
2/2
✓ Branch 0 taken 2894 times.
✓ Branch 1 taken 11216 times.
14110 if (test_if_skip_sort_order(tab, group_list, limit, false,
1643
1/2
✓ Branch 0 taken 14110 times.
✗ Branch 1 not taken.
14110 &tab->table()->keys_in_use_for_group_by,
1644 &dummy)) {
1645 2894 m_ordered_index_usage = ORDERED_INDEX_GROUP_BY;
1646 }
1647 }
1648
1649 /*
1650 If we are going to use semi-join LooseScan, it will depend
1651 on the selected index scan to be used. If index is not used
1652 for the GROUP BY, we risk that sorting is put on the LooseScan
1653 table. In order to avoid this, force use of temporary table.
1654 TODO: Explain the allow_group_via_temp_table part of the test below.
1655 */
1656
4/4
✓ Branch 0 taken 13113 times.
✓ Branch 1 taken 2894 times.
✓ Branch 2 taken 11551 times.
✓ Branch 3 taken 4456 times.
29120 if ((m_ordered_index_usage != ORDERED_INDEX_GROUP_BY) &&
1657
2/2
✓ Branch 0 taken 1562 times.
✓ Branch 1 taken 11551 times.
13113 (tmp_table_param.allow_group_via_temp_table ||
1658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1562 times.
1562 (tab->emb_sj_nest &&
1659 tab->position()->sj_strategy == SJ_OPT_LOOSE_SCAN))) {
1660 11551 need_tmp_before_win = true;
1661 11551 simple_order = simple_group = false; // Force tmp table without sort
1662 }
1663 }
1664 1714843 } else if (!order.empty() && // ORDER BY wo/ preceding GROUP BY
1665
2/2
✓ Branch 0 taken 241833 times.
✓ Branch 1 taken 299516 times.
541349 (simple_order ||
1666
5/6
✓ Branch 0 taken 541349 times.
✓ Branch 1 taken 1173418 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 241833 times.
✓ Branch 4 taken 299433 times.
✓ Branch 5 taken 1415334 times.
2256116 skip_sort_order) && // which is possibly skippable,
1667
2/2
✓ Branch 0 taken 299433 times.
✓ Branch 1 taken 83 times.
299516 !m_windows_sort) // and WFs will not shuffle rows
1668 {
1669 int dummy;
1670
2/2
✓ Branch 0 taken 18555 times.
✓ Branch 1 taken 280878 times.
299433 if ((skip_sort_order = test_if_skip_sort_order(
1671 299433 tab, order, m_select_limit, false,
1672
1/2
✓ Branch 0 taken 299433 times.
✗ Branch 1 not taken.
299433 &tab->table()->keys_in_use_for_order_by, &dummy))) {
1673 18555 m_ordered_index_usage = ORDERED_INDEX_ORDER_BY;
1674 }
1675 }
1676 1730903 }
1677
1678 /**
1679 Test if ORDER BY is a single MATCH function(ORDER BY MATCH)
1680 and sort order is descending.
1681
1682 @param order pointer to ORDER struct.
1683
1684 @retval
1685 Pointer to MATCH function if order is 'ORDER BY MATCH() DESC'
1686 @retval
1687 NULL otherwise
1688 */
1689
1690 299897 static Item_func_match *test_if_ft_index_order(ORDER *order) {
1691
7/8
✓ Branch 0 taken 299897 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 229620 times.
✓ Branch 3 taken 70277 times.
✓ Branch 4 taken 4080 times.
✓ Branch 5 taken 225540 times.
✓ Branch 6 taken 72 times.
✓ Branch 7 taken 299825 times.
303977 if (order && order->next == nullptr && order->direction == ORDER_DESC &&
1692
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 4008 times.
4080 is_function_of_type(*order->item, Item_func::FT_FUNC))
1693 72 return down_cast<Item_func_match *>(*order->item)->get_master();
1694
1695 299825 return nullptr;
1696 }
1697
1698 /**
1699 Test if this is a prefix index.
1700
1701 @param table table
1702 @param idx index to check
1703
1704 @return TRUE if this is a prefix index
1705 */
1706 64 bool is_prefix_index(TABLE *table, uint idx) {
1707
2/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
64 if (!table || !table->key_info) {
1708 return false;
1709 }
1710
1711 64 KEY *key_info = table->key_info;
1712 64 uint key_parts = key_info[idx].user_defined_key_parts;
1713 64 KEY_PART_INFO *key_part = key_info[idx].key_part;
1714
1715
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 62 times.
192 for (uint i = 0; i < key_parts; i++, key_part++) {
1716 390 if (key_part->field &&
1717
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 128 times.
130 !(table->field[key_part->fieldnr - 1]
1718
3/4
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 128 times.
260 ->part_of_prefixkey.is_clear_all()) &&
1719
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 !(key_info->flags & (HA_FULLTEXT | HA_SPATIAL))) {
1720 2 return true;
1721 }
1722 }
1723 62 return false;
1724 }
1725
1726 /**
1727 Test if one can use the key to resolve ordering.
1728
1729 @param order_src Sort order
1730 @param table Table to sort
1731 @param idx Index to check
1732 @param[out] used_key_parts NULL by default, otherwise return value for
1733 used key parts.
1734 @param[out] skip_quick Whether found index can be used for backward range
1735 scans
1736
1737 @note
1738 used_key_parts is set to correct key parts used if return value != 0
1739 (On other cases, used_key_part may be changed)
1740 Note that the value may actually be greater than the number of index
1741 key parts. This can happen for storage engines that have the primary
1742 key parts as a suffix for every secondary key.
1743
1744 @retval
1745 1 key is ok.
1746 @retval
1747 0 Key can't be used
1748 @retval
1749 -1 Reverse key can be used
1750 */
1751
1752 65408 int test_if_order_by_key(ORDER_with_src *order_src, TABLE *table, uint idx,
1753 uint *used_key_parts, bool *skip_quick) {
1754
1/2
✓ Branch 0 taken 65408 times.
✗ Branch 1 not taken.
65408 DBUG_TRACE;
1755 KEY_PART_INFO *key_part, *key_part_end;
1756 65408 key_part = table->key_info[idx].key_part;
1757 65408 key_part_end = key_part + table->key_info[idx].user_defined_key_parts;
1758 65408 key_part_map const_key_parts = table->const_key_parts[idx];
1759 65408 int reverse = 0;
1760 uint key_parts;
1761 65408 bool on_pk_suffix = false;
1762 // Whether [extended] key has key parts with mixed ASC/DESC order
1763 65408 bool mixed_order = false;
1764 // Order direction of the first key part
1765 65408 bool reverse_sorted = (bool)(key_part->key_part_flag & HA_REVERSE_SORT);
1766 65408 ORDER *order = order_src->order;
1767 65408 *skip_quick = false;
1768
1769
2/2
✓ Branch 0 taken 73700 times.
✓ Branch 1 taken 54604 times.
128304 for (; order; order = order->next, const_key_parts >>= 1) {
1770 /*
1771 Since only fields can be indexed, ORDER BY <something> that is
1772 not a field cannot be resolved by using an index.
1773 */
1774
1/2
✓ Branch 0 taken 73700 times.
✗ Branch 1 not taken.
73700 Item *real_itm = (*order->item)->real_item();
1775
3/4
✓ Branch 0 taken 73700 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 73674 times.
73700 if (real_itm->type() != Item::FIELD_ITEM) return 0;
1776
1777 73674 const Field *field = down_cast<const Item_field *>(real_itm)->field;
1778
1779 /*
1780 Skip key parts that are constants in the WHERE clause.
1781 These are already skipped in the ORDER BY by check_field_is_const()
1782 */
1783
4/4
✓ Branch 0 taken 3753 times.
✓ Branch 1 taken 73668 times.
✓ Branch 2 taken 3747 times.
✓ Branch 3 taken 6 times.
77421 for (; const_key_parts & 1 && key_part < key_part_end;
1784 3747 const_key_parts >>= 1)
1785 3747 key_part++;
1786
1787 /* Avoid usage of prefix index for sorting a partition table */
1788
4/4
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 1606 times.
✓ Branch 2 taken 64 times.
✓ Branch 3 taken 5 times.
1675 if (table->part_info && key_part != table->key_info[idx].key_part &&
1789
7/8
✓ Branch 0 taken 1675 times.
✓ Branch 1 taken 71999 times.
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 62 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 73672 times.
75349 key_part != key_part_end && is_prefix_index(table, idx))
1790 2 return 0;
1791
1792
2/2
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 73040 times.
73672 if (key_part == key_part_end) {
1793 /*
1794 We are at the end of the key. Check if the engine has the primary
1795 key as a suffix to the secondary keys. If it has continue to check
1796 the primary key as a suffix.
1797 */
1798 1896 if (!on_pk_suffix &&
1799
2/2
✓ Branch 0 taken 615 times.
✓ Branch 1 taken 17 times.
632 (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
1800
7/8
✓ Branch 0 taken 632 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 395 times.
✓ Branch 3 taken 220 times.
✓ Branch 4 taken 343 times.
✓ Branch 5 taken 52 times.
✓ Branch 6 taken 343 times.
✓ Branch 7 taken 289 times.
1264 table->s->primary_key != MAX_KEY && table->s->primary_key != idx) {
1801 343 on_pk_suffix = true;
1802 343 key_part = table->key_info[table->s->primary_key].key_part;
1803 343 key_part_end =
1804 343 key_part +
1805 343 table->key_info[table->s->primary_key].user_defined_key_parts;
1806 343 const_key_parts = table->const_key_parts[table->s->primary_key];
1807
1808
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 343 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
352 for (; const_key_parts & 1 && key_part < key_part_end;
1809 9 const_key_parts >>= 1)
1810 9 key_part++;
1811 /*
1812 The primary and secondary key parts were all const (i.e. there's
1813 one row). The sorting doesn't matter.
1814 */
1815
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 343 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
343 if (key_part == key_part_end && reverse == 0) {
1816 key_parts = 0;
1817 reverse = 1;
1818 goto ok;
1819 }
1820 } else
1821 289 return 0;
1822 }
1823
1824
6/6
✓ Branch 0 taken 67183 times.
✓ Branch 1 taken 6200 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 67153 times.
✓ Branch 4 taken 6230 times.
✓ Branch 5 taken 67153 times.
73383 if (key_part->field != field || !field->part_of_sortkey.is_set(idx))
1825 6230 return 0;
1826
2/2
✓ Branch 0 taken 63457 times.
✓ Branch 1 taken 3696 times.
67153 if (order->direction != ORDER_NOT_RELEVANT) {
1827 63457 const enum_order keypart_order =
1828
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 63281 times.
63457 (key_part->key_part_flag & HA_REVERSE_SORT) ? ORDER_DESC : ORDER_ASC;
1829 /* set flag to 1 if we can use read-next on key, else to -1 */
1830
2/2
✓ Branch 0 taken 52571 times.
✓ Branch 1 taken 10886 times.
63457 int cur_scan_dir = (order->direction == keypart_order) ? 1 : -1;
1831
4/4
✓ Branch 0 taken 7844 times.
✓ Branch 1 taken 55613 times.
✓ Branch 2 taken 4257 times.
✓ Branch 3 taken 3587 times.
63457 if (reverse && cur_scan_dir != reverse) return 0;
1832 59200 reverse = cur_scan_dir; // Remember if reverse
1833 }
1834 62896 mixed_order |=
1835 62896 (reverse_sorted != (bool)((key_part)->key_part_flag & HA_REVERSE_SORT));
1836
1837 62896 key_part++;
1838 }
1839 /*
1840 The index picked here might be used for range scans with multiple ranges.
1841 This will require tricky reordering in case of ranges would have to be
1842 scanned backward and index consists of mixed ASC/DESC key parts. Due to that
1843 backward scans on such indexes are disabled.
1844 */
1845
4/4
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 54439 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 130 times.
54604 if (mixed_order && reverse < 0) *skip_quick = true;
1846
1847
2/2
✓ Branch 0 taken 3577 times.
✓ Branch 1 taken 51027 times.
54604 if (!reverse) {
1848 /*
1849 We get here when the key is suitable and we don't care about it's
1850 order, i.e. GROUP BY/DISTINCT. Use forward scan.
1851 */
1852 3577 reverse = 1;
1853 }
1854
2/2
✓ Branch 0 taken 198 times.
✓ Branch 1 taken 54406 times.
54604 if (on_pk_suffix) {
1855 198 uint used_key_parts_secondary = table->key_info[idx].user_defined_key_parts;
1856 198 uint used_key_parts_pk =
1857 198 (uint)(key_part - table->key_info[table->s->primary_key].key_part);
1858 198 key_parts = used_key_parts_pk + used_key_parts_secondary;
1859
1860
3/4
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 198 times.
320 if (reverse == -1 &&
1861
2/4
✓ Branch 0 taken 122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 122 times.
✗ Branch 3 not taken.
122 (!(table->file->index_flags(idx, used_key_parts_secondary - 1, true) &
1862 122 HA_READ_PREV) ||
1863
1/2
✓ Branch 0 taken 122 times.
✗ Branch 1 not taken.
122 !(table->file->index_flags(table->s->primary_key,
1864
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 122 times.
122 used_key_parts_pk - 1, true) &
1865 HA_READ_PREV)))
1866 reverse = 0; // Index can't be used
1867 } else {
1868 54406 key_parts = (uint)(key_part - table->key_info[idx].key_part);
1869
3/4
✓ Branch 0 taken 6307 times.
✓ Branch 1 taken 48099 times.
✓ Branch 2 taken 54406 times.
✗ Branch 3 not taken.
60713 if (reverse == -1 &&
1870
2/4
✓ Branch 0 taken 6307 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6307 times.
6307 !(table->file->index_flags(idx, key_parts - 1, true) & HA_READ_PREV))
1871 reverse = 0; // Index can't be used
1872 }
1873 54406 ok:
1874
2/2
✓ Branch 0 taken 53233 times.
✓ Branch 1 taken 1371 times.
54604 if (used_key_parts != nullptr) *used_key_parts = key_parts;
1875 54604 return reverse;
1876 65408 }
1877
1878 /**
1879 Find shortest key suitable for full table scan.
1880
1881 @param table Table to scan
1882 @param usable_keys Allowed keys
1883
1884 @note
1885 As far as
1886 1) clustered primary key entry data set is a set of all record
1887 fields (key fields and not key fields) and
1888 2) secondary index entry data is a union of its key fields and
1889 primary key fields (at least InnoDB and its derivatives don't
1890 duplicate primary key fields there, even if the primary and
1891 the secondary keys have a common subset of key fields),
1892 then secondary index entry data is always a subset of primary key entry.
1893 Unfortunately, key_info[nr].key_length doesn't show the length
1894 of key/pointer pair but a sum of key field lengths only, thus
1895 we can't estimate index IO volume comparing only this key_length
1896 value of secondary keys and clustered PK.
1897 So, try secondary keys first, and choose PK only if there are no
1898 usable secondary covering keys or found best secondary key include
1899 all table fields (i.e. same as PK):
1900
1901 @return
1902 MAX_KEY no suitable key found
1903 key index otherwise
1904 */
1905
1906 1750115 uint find_shortest_key(TABLE *table, const Key_map *usable_keys) {
1907 1750115 uint best = MAX_KEY;
1908 1750115 uint usable_clustered_pk = (table->file->primary_key_is_clustered() &&
1909
4/4
✓ Branch 0 taken 714920 times.
✓ Branch 1 taken 372665 times.
✓ Branch 2 taken 359335 times.
✓ Branch 3 taken 355555 times.
1802475 table->s->primary_key != MAX_KEY &&
1910 714920 usable_keys->is_set(table->s->primary_key))
1911
2/2
✓ Branch 0 taken 1087585 times.
✓ Branch 1 taken 662632 times.
2837772 ? table->s->primary_key
1912 1750187 : MAX_KEY;
1913
2/2
✓ Branch 0 taken 548313 times.
✓ Branch 1 taken 1201888 times.
1750187 if (!usable_keys->is_clear_all()) {
1914 548313 uint min_length = (uint)~0;
1915
2/2
✓ Branch 0 taken 953055 times.
✓ Branch 1 taken 548319 times.
1501374 for (uint nr = 0; nr < table->s->keys; nr++) {
1916
2/2
✓ Branch 0 taken 359329 times.
✓ Branch 1 taken 593726 times.
953055 if (nr == usable_clustered_pk) continue;
1917
2/2
✓ Branch 0 taken 433041 times.
✓ Branch 1 taken 160691 times.
593726 if (usable_keys->is_set(nr)) {
1918 /*
1919 Can not do full index scan on rtree index because it is not
1920 supported by Innodb, probably not supported by others either.
1921 A multi-valued key requires unique filter, and won't be the most
1922 fast option even if it will be the shortest one.
1923 */
1924 433041 const KEY &key_ref = table->key_info[nr];
1925
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 433041 times.
433041 assert(!(key_ref.flags & HA_MULTI_VALUED_KEY));
1926
4/4
✓ Branch 0 taken 426627 times.
✓ Branch 1 taken 6414 times.
✓ Branch 2 taken 426251 times.
✓ Branch 3 taken 376 times.
433041 if (key_ref.key_length < min_length && !(key_ref.flags & HA_SPATIAL)) {
1927 426251 min_length = key_ref.key_length;
1928 426251 best = nr;
1929 }
1930 }
1931 }
1932 }
1933
2/2
✓ Branch 0 taken 359356 times.
✓ Branch 1 taken 1390851 times.
1750207 if (usable_clustered_pk != MAX_KEY) {
1934 /*
1935 If the primary key is clustered and found shorter key covers all table
1936 fields and is not clustering then primary key scan normally would be
1937 faster because amount of data to scan is the same but PK is clustered.
1938 It's safe to compare key parts with table fields since duplicate key
1939 parts aren't allowed.
1940 */
1941
4/4
✓ Branch 0 taken 236829 times.
✓ Branch 1 taken 122527 times.
✓ Branch 2 taken 122609 times.
✓ Branch 3 taken 236747 times.
596185 if (best == MAX_KEY ||
1942
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 236753 times.
236829 ((table->key_info[best].user_defined_key_parts >= table->s->fields) &&
1943
1/2
✓ Branch 0 taken 82 times.
✗ Branch 1 not taken.
76 !(table->file->index_flags(best, 0, 0) & HA_CLUSTERED_INDEX)))
1944 122609 best = usable_clustered_pk;
1945 }
1946 1750207 return best;
1947 }
1948
1949 /**
1950 Test if a second key is the subkey of the first one.
1951
1952 @param key_part First key parts
1953 @param ref_key_part Second key parts
1954 @param ref_key_part_end Last+1 part of the second key
1955
1956 @note
1957 Second key MUST be shorter than the first one.
1958
1959 @retval
1960 1 is a subkey
1961 @retval
1962 0 no sub key
1963 */
1964
1965 1207 inline bool is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
1966 KEY_PART_INFO *ref_key_part_end) {
1967
2/2
✓ Branch 0 taken 1207 times.
✓ Branch 1 taken 384 times.
1591 for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
1968
2/2
✓ Branch 0 taken 823 times.
✓ Branch 1 taken 384 times.
1207 if (!key_part->field->eq(ref_key_part->field)) return false;
1969 384 return true;
1970 }
1971
1972 /**
1973 Test if REF_OR_NULL optimization will be used if the specified
1974 ref_key is used for REF-access to 'tab'
1975
1976 @retval
1977 true JT_REF_OR_NULL will be used
1978 @retval
1979 false no JT_REF_OR_NULL access
1980 */
1981
1982 384 static bool is_ref_or_null_optimized(const JOIN_TAB *tab, uint ref_key) {
1983
2/2
✓ Branch 0 taken 363 times.
✓ Branch 1 taken 21 times.
384 if (tab->keyuse()) {
1984 363 const Key_use *keyuse = tab->keyuse();
1985
3/4
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 363 times.
✓ Branch 2 taken 315 times.
✗ Branch 3 not taken.
678 while (keyuse->key != ref_key && keyuse->table_ref == tab->table_ref)
1986 315 keyuse++;
1987
1988 363 const table_map const_tables = tab->join()->const_table_map;
1989
3/4
✓ Branch 0 taken 395 times.
✓ Branch 1 taken 331 times.
✓ Branch 2 taken 395 times.
✗ Branch 3 not taken.
726 while (keyuse->key == ref_key && keyuse->table_ref == tab->table_ref) {
1990
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 18 times.
395 if (!(keyuse->used_tables & ~const_tables)) {
1991
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 345 times.
377 if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) return true;
1992 }
1993 363 keyuse++;
1994 }
1995 }
1996 352 return false;
1997 }
1998
1999 /**
2000 Test if we can use one of the 'usable_keys' instead of 'ref' key
2001 for sorting.
2002
2003 @param order The query block's order clause.
2004 @param tab Current JOIN_TAB.
2005 @param ref Number of key, used for WHERE clause
2006 @param ref_key_parts Index columns used for ref lookup.
2007 @param usable_keys Keys for testing
2008
2009 @return
2010 - MAX_KEY If we can't use other key
2011 - the number of found key Otherwise
2012 */
2013
2014 1183 static uint test_if_subkey(ORDER_with_src *order, JOIN_TAB *tab, uint ref,
2015 uint ref_key_parts, const Key_map *usable_keys) {
2016 uint nr;
2017 1183 uint min_length = (uint)~0;
2018 1183 uint best = MAX_KEY;
2019 1183 TABLE *table = tab->table();
2020 1183 KEY_PART_INFO *ref_key_part = table->key_info[ref].key_part;
2021 1183 KEY_PART_INFO *ref_key_part_end = ref_key_part + ref_key_parts;
2022
2023
2/2
✓ Branch 0 taken 3532 times.
✓ Branch 1 taken 1183 times.
4715 for (nr = 0; nr < table->s->keys; nr++) {
2024 bool skip_quick;
2025 3532 if (usable_keys->is_set(nr) &&
2026
2/2
✓ Branch 0 taken 1207 times.
✓ Branch 1 taken 2 times.
1209 table->key_info[nr].key_length < min_length &&
2027
1/2
✓ Branch 0 taken 1207 times.
✗ Branch 1 not taken.
1207 table->key_info[nr].user_defined_key_parts >= ref_key_parts &&
2028
3/4
✓ Branch 0 taken 1207 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 384 times.
✓ Branch 3 taken 823 times.
1207 is_subkey(table->key_info[nr].key_part, ref_key_part,
2029 384 ref_key_part_end) &&
2030
2/2
✓ Branch 0 taken 352 times.
✓ Branch 1 taken 32 times.
384 !is_ref_or_null_optimized(tab, nr) &&
2031
7/8
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 2323 times.
✓ Branch 2 taken 352 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 347 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 347 times.
✓ Branch 7 taken 3185 times.
5088 test_if_order_by_key(order, table, nr, nullptr, &skip_quick) &&
2032
1/2
✓ Branch 0 taken 347 times.
✗ Branch 1 not taken.
347 !skip_quick) {
2033 347 min_length = table->key_info[nr].key_length;
2034 347 best = nr;
2035 }
2036 }
2037 1183 return best;
2038 }
2039
2040 /**
2041 It is not obvious to see that test_if_skip_sort_order() never changes the
2042 plan if no_changes is true. So we double-check: creating an instance of this
2043 class saves some important access-path-related information of the current
2044 table; when the instance is destroyed, the latest access-path information is
2045 compared with saved data.
2046 */
2047
2048 class Plan_change_watchdog {
2049 #ifndef NDEBUG
2050 public:
2051 /**
2052 @param tab_arg table whose access path is being determined
2053 @param no_changes_arg whether a change to the access path is allowed
2054 */
2055 313823 Plan_change_watchdog(const JOIN_TAB *tab_arg, const bool no_changes_arg) {
2056
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 313543 times.
313823 if (no_changes_arg) {
2057 280 tab = tab_arg;
2058 280 type = tab->type();
2059
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 271 times.
280 if ((quick = tab->range_scan())) quick_index = used_index(quick);
2060 280 use_quick = tab->use_quick;
2061 280 ref_key = tab->ref().key;
2062 280 ref_key_parts = tab->ref().key_parts;
2063 280 index = tab->index();
2064 } else {
2065 313543 tab = nullptr;
2066 313543 type = JT_UNKNOWN;
2067 313543 quick = nullptr;
2068 313543 ref_key = ref_key_parts = index = 0;
2069 313543 use_quick = QS_NONE;
2070 }
2071 313823 }
2072 314103 ~Plan_change_watchdog() {
2073
2/2
✓ Branch 0 taken 313543 times.
✓ Branch 1 taken 280 times.
313823 if (tab == nullptr) return;
2074 // changes are not allowed, we verify:
2075
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 assert(tab->type() == type);
2076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 assert(tab->range_scan() == quick);
2077
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 271 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
280 assert(quick == nullptr || used_index(tab->range_scan()) == quick_index);
2078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 assert(tab->use_quick == use_quick);
2079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 assert(tab->ref().key == ref_key);
2080
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 assert(tab->ref().key_parts == ref_key_parts);
2081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 assert(tab->index() == index);
2082 313823 }
2083
2084 private:
2085 const JOIN_TAB *tab; ///< table, or NULL if changes are allowed
2086 enum join_type type; ///< copy of tab->type()
2087 // "Range / index merge" info
2088 const AccessPath *quick{nullptr}; ///< copy of tab->select->quick
2089 uint quick_index{0}; ///< copy of tab->select->quick->index
2090 enum quick_type use_quick; ///< copy of tab->use_quick
2091 // "ref access" info
2092 int ref_key; ///< copy of tab->ref().key
2093 uint ref_key_parts; /// copy of tab->ref().key_parts
2094 // Other index-related info
2095 uint index; ///< copy of tab->index
2096 #else // in non-debug build, empty class
2097 public:
2098 Plan_change_watchdog(const JOIN_TAB *, const bool) {}
2099 #endif
2100 };
2101
2102 /**
2103 Test if we can skip ordering by using an index.
2104
2105 If the current plan is to use an index that provides ordering, the
2106 plan will not be changed. Otherwise, if an index can be used, the
2107 JOIN_TAB / tab->select struct is changed to use the index.
2108
2109 The index must cover all fields in @<order@>, or it will not be considered.
2110
2111 @param tab NULL or JOIN_TAB of the accessed table
2112 @param order Linked list of ORDER BY arguments
2113 @param select_limit LIMIT value, or HA_POS_ERROR if no limit
2114 @param no_changes No changes will be made to the query plan.
2115 @param map Key_map of applicable indexes.
2116 @param [out] order_idx Number of index selected, -1 if no applicable index
2117 found
2118
2119 @todo
2120 - sergeyp: Results of all index merge selects actually are ordered
2121 by clustered PK values.
2122
2123 @note
2124 This function may change tmp_table_param.precomputed_group_by. This
2125 affects how create_tmp_table() treats aggregation functions, so
2126 count_field_types() must be called again to make sure this is taken
2127 into consideration.
2128
2129 @retval
2130 0 We have to use filesort to do the sorting
2131 @retval
2132 1 We can use an index.
2133 */
2134
2135 313823 static bool test_if_skip_sort_order(JOIN_TAB *tab, ORDER_with_src &order,
2136 ha_rows select_limit, const bool no_changes,
2137 const Key_map *map, int *order_idx) {
2138
1/2
✓ Branch 0 taken 313823 times.
✗ Branch 1 not taken.
313823 DBUG_TRACE;
2139 int ref_key;
2140 313823 uint ref_key_parts = 0;
2141 313823 int order_direction = 0;
2142 313823 uint used_key_parts = 0;
2143 313823 TABLE *const table = tab->table();
2144 313823 JOIN *const join = tab->join();
2145 313823 THD *const thd = join->thd;
2146 313823 AccessPath *const save_range_scan = tab->range_scan();
2147 313823 int best_key = -1;
2148 313823 bool set_up_ref_access_to_key = false;
2149 313823 bool can_skip_sorting = false; // used as return value
2150 313823 int changed_key = -1;
2151
2152 /* Check that we are always called with first non-const table */
2153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 313823 times.
313823 assert((uint)tab->idx() == join->const_tables);
2154
2155 313823 Plan_change_watchdog watchdog(tab, no_changes);
2156 313823 *order_idx = -1;
2157 /* Sorting a single row can always be skipped */
2158
7/8
✓ Branch 0 taken 313814 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 313813 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 313813 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 313813 times.
627636 if (tab->type() == JT_EQ_REF || tab->type() == JT_CONST ||
2159 313813 tab->type() == JT_SYSTEM) {
2160 10 return true;
2161 }
2162
2163 /*
2164 Check if FT index can be used to retrieve result in the required order.
2165 It is possible if ordering is on the first non-constant table.
2166 */
2167
6/6
✓ Branch 0 taken 300085 times.
✓ Branch 1 taken 13728 times.
✓ Branch 2 taken 299833 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 299833 times.
✓ Branch 5 taken 13980 times.
313813 if (!join->order.empty() && join->simple_order) {
2168 /*
2169 Check if ORDER is DESC, ORDER BY is a single MATCH function.
2170 */
2171
1/2
✓ Branch 0 taken 299833 times.
✗ Branch 1 not taken.
299833 Item_func_match *ft_func = test_if_ft_index_order(order.order);
2172 /*
2173 Two possible cases when we can skip sort order:
2174 1. FT_SORTED must be set(Natural mode, no ORDER BY).
2175 2. If FT_SORTED flag is not set then
2176 the engine should support deferred sorting. Deferred sorting means
2177 that sorting is postponed utill the start of index reading(InnoDB).
2178 In this case we set FT_SORTED flag here to let the engine know that
2179 internal sorting is needed.
2180 */
2181
9/10
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 299782 times.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 45 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 45 times.
✓ Branch 9 taken 299788 times.
299833 if (ft_func && ft_func->ft_handler && ft_func->ordered_result()) {
2182 /*
2183 FT index scan is used, so the only additional requirement is
2184 that ORDER BY MATCH function is the same as the function that
2185 is used for FT index.
2186 */
2187
4/4
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 24 times.
71 if (tab->type() == JT_FT &&
2188
3/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 5 times.
26 ft_func->eq(tab->position()->key->val, true)) {
2189
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 ft_func->set_hints(join, FT_SORTED, select_limit, false);
2190 21 return true;
2191 }
2192 /*
2193 No index is used, it's possible to use FT index for ORDER BY if
2194 LIMIT is present and does not exceed count of the records in FT index
2195 and there is no WHERE condition since a condition may potentially
2196 require more rows to be fetch from FT index.
2197 */
2198
6/6
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 14 times.
36 if (!tab->condition() && select_limit != HA_POS_ERROR &&
2199
3/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 2 times.
12 select_limit <= ft_func->get_count()) {
2200 /* test_if_ft_index_order() always returns master MATCH function. */
2201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 assert(!ft_func->master);
2202 /* ref is not set since there is no WHERE condition */
2203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 assert(tab->ref().key == -1);
2204
2205 /*Make EXPLAIN happy */
2206 10 tab->set_type(JT_FT);
2207 10 tab->ref().key = ft_func->key;
2208 10 tab->ref().key_parts = 0;
2209 10 tab->set_index(ft_func->key);
2210 10 tab->set_ft_func(ft_func);
2211
2212 /* Setup FT handler */
2213
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 ft_func->set_hints(join, FT_SORTED, select_limit, true);
2214 10 ft_func->score_from_index_scan = true;
2215 10 table->file->ft_handler = ft_func->ft_handler;
2216 10 return true;
2217 }
2218 }
2219 }
2220
2221 /*
2222 Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
2223 been taken into account.
2224 */
2225 313782 Key_map usable_keys = *map;
2226
2227
2/2
✓ Branch 0 taken 325215 times.
✓ Branch 1 taken 52866 times.
378081 for (ORDER *tmp_order = order.order; tmp_order; tmp_order = tmp_order->next) {
2228
1/2
✓ Branch 0 taken 325215 times.
✗ Branch 1 not taken.
325215 const Item *item = (*tmp_order->item)->real_item();
2229
3/4
✓ Branch 0 taken 325215 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13000 times.
✓ Branch 3 taken 312215 times.
325215 if (item->type() != Item::FIELD_ITEM) {
2230 13000 usable_keys.clear_all();
2231 13000 return false;
2232 }
2233 312215 usable_keys.intersect(
2234 312215 down_cast<const Item_field *>(item)->field->part_of_sortkey);
2235
2/2
✓ Branch 0 taken 247916 times.
✓ Branch 1 taken 64299 times.
312215 if (usable_keys.is_clear_all()) return false; // No usable keys
2236 }
2237
6/6
✓ Branch 0 taken 52863 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 52828 times.
✓ Branch 4 taken 38 times.
✓ Branch 5 taken 52828 times.
52866 if (tab->type() == JT_REF_OR_NULL || tab->type() == JT_FT) return false;
2238
2239 52828 ref_key = -1;
2240 /* Test if constant range in WHERE */
2241
2/2
✓ Branch 0 taken 1948 times.
✓ Branch 1 taken 50880 times.
52828 if (tab->type() == JT_REF) {
2242
2/4
✓ Branch 0 taken 1948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1948 times.
✗ Branch 3 not taken.
1948 assert(tab->ref().key >= 0 && tab->ref().key_parts);
2243 1948 ref_key = tab->ref().key;
2244 1948 ref_key_parts = tab->ref().key_parts;
2245
6/6
✓ Branch 0 taken 44429 times.
✓ Branch 1 taken 6451 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 44377 times.
✓ Branch 4 taken 6503 times.
✓ Branch 5 taken 44377 times.
50880 } else if (tab->type() == JT_RANGE || tab->type() == JT_INDEX_MERGE) {
2246 // Range found by opt_range
2247 /*
2248 assume results are not ordered when index merge is used
2249 TODO: sergeyp: Results of all index merge selects actually are ordered
2250 by clustered PK values.
2251 */
2252
2253 6503 if (tab->range_scan()->type == AccessPath::INDEX_MERGE ||
2254
6/6
✓ Branch 0 taken 6467 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 6459 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 52 times.
✓ Branch 5 taken 6451 times.
12962 tab->range_scan()->type == AccessPath::ROWID_UNION ||
2255
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6451 times.
6459 tab->range_scan()->type == AccessPath::ROWID_INTERSECTION)
2256 52 return false;
2257 6451 ref_key = used_index(tab->range_scan());
2258 6451 ref_key_parts = get_used_key_parts(tab->range_scan());
2259
2/2
✓ Branch 0 taken 4057 times.
✓ Branch 1 taken 40320 times.
44377 } else if (tab->type() == JT_INDEX_SCAN) {
2260 // The optimizer has decided to use an index scan.
2261 4057 ref_key = tab->index();
2262
1/2
✓ Branch 0 taken 4057 times.
✗ Branch 1 not taken.
4057 ref_key_parts = actual_key_parts(&table->key_info[tab->index()]);
2263 }
2264
2265 52776 Opt_trace_context *const trace = &thd->opt_trace;
2266
1/2
✓ Branch 0 taken 52776 times.
✗ Branch 1 not taken.
52776 Opt_trace_object trace_wrapper_1(trace);
2267 Opt_trace_object trace_skip_sort_order(
2268
1/2
✓ Branch 0 taken 52776 times.
✗ Branch 1 not taken.
52776 trace, "reconsidering_access_paths_for_index_ordering");
2269
1/2
✓ Branch 0 taken 52776 times.
✗ Branch 1 not taken.
52776 trace_skip_sort_order.add_alnum(
2270
2/2
✓ Branch 0 taken 49567 times.
✓ Branch 1 taken 3209 times.
52776 "clause", (order.src == ESC_ORDER_BY ? "ORDER BY" : "GROUP BY"));
2271
1/2
✓ Branch 0 taken 52776 times.
✗ Branch 1 not taken.
52776 Opt_trace_array trace_steps(trace, "steps");
2272
2273
2/2
✓ Branch 0 taken 12456 times.
✓ Branch 1 taken 40320 times.
52776 if (ref_key >= 0) {
2274 /*
2275 We come here when ref/index scan/range scan access has been set
2276 up for this table. Do not change access method if ordering is
2277 provided already.
2278 */
2279
2/2
✓ Branch 0 taken 1183 times.
✓ Branch 1 taken 11273 times.
12456 if (!usable_keys.is_set(ref_key)) {
2280 /*
2281 We come here when ref_key is not among usable_keys, try to find a
2282 usable prefix key of that key.
2283 */
2284 uint new_ref_key;
2285 /*
2286 If using index only read, only consider other possible index only
2287 keys
2288 */
2289
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1182 times.
1183 if (table->covering_keys.is_set(ref_key))
2290 1 usable_keys.intersect(table->covering_keys);
2291
2292
1/2
✓ Branch 0 taken 1183 times.
✗ Branch 1 not taken.
1183 if ((new_ref_key = test_if_subkey(&order, tab, ref_key, ref_key_parts,
2293
2/2
✓ Branch 0 taken 347 times.
✓ Branch 1 taken 836 times.
1183 &usable_keys)) < MAX_KEY) {
2294 /* Found key that can be used to retrieve data in sorted order */
2295
2/2
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 16 times.
347 if (tab->ref().key >= 0) {
2296 /*
2297 We'll use ref access method on key new_ref_key. The actual change
2298 is done further down in this function where we update the plan.
2299 */
2300 331 set_up_ref_access_to_key = true;
2301
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 } else if (!no_changes) {
2302 /*
2303 The range optimizer constructed QUICK_RANGE for ref_key, and
2304 we want to use instead new_ref_key as the index. We can't
2305 just change the index of the quick select, because this may
2306 result in an inconsistent RowIterator object. Below we
2307 create a new RowIterator from scratch so that all its
2308 parameres are set correctly by the range optimizer.
2309
2310 Note that the range optimizer is NOT called if
2311 no_changes==true. This reason is that the range optimizer
2312 cannot find a QUICK that can return ordered result unless
2313 index access (ref or index scan) is also able to do so
2314 (which test_if_order_by_key () will tell).
2315 Admittedly, range access may be much more efficient than
2316 e.g. index scan, but the only thing that matters when
2317 no_change==true is the answer to the question: "Is it
2318 possible to avoid sorting if an index is used to access
2319 this table?". The answer does not depend on the outcome of
2320 the range optimizer.
2321 */
2322
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 Key_map new_ref_key_map; // Force the creation of quick select
2323 14 new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
2324
2325
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 Opt_trace_object trace_wrapper_2(trace);
2326
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 Opt_trace_object trace_recest(trace, "rows_estimation");
2327
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 trace_recest.add_utf8_table(tab->table_ref)
2328
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 .add_utf8("index", table->key_info[new_ref_key].name);
2329 AccessPath *range_scan;
2330 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
2331 14 thd->variables.range_alloc_block_size);
2332 const bool no_quick =
2333
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
28 test_quick_select(
2334 thd, thd->mem_root, &temp_mem_root, new_ref_key_map, 0,
2335 0, // empty table_map
2336 14 join->calc_found_rows
2337 ? HA_POS_ERROR
2338 14 : join->query_expression()->select_limit_cnt,
2339 false, // don't force quick range
2340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 order.order->direction, tab->table(),
2341 14 tab->skip_records_in_range(),
2342 // we are after make_join_query_block():
2343 14 tab->condition(), &tab->needed_reg, tab->table()->force_index,
2344 14 join->query_block, &range_scan) <= 0;
2345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(tab->range_scan() == save_range_scan);
2346 14 tab->set_range_scan(range_scan);
2347
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
14 if (no_quick) {
2348 3 can_skip_sorting = false;
2349 3 goto fix_ICP;
2350 }
2351
6/6
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 3 times.
20 }
2352 344 ref_key = new_ref_key;
2353 344 changed_key = new_ref_key;
2354 }
2355 }
2356 bool dummy;
2357 /* Check if we get the rows in requested sorted order by using the key */
2358
2/2
✓ Branch 0 taken 11617 times.
✓ Branch 1 taken 836 times.
12453 if (usable_keys.is_set(ref_key))
2359 // Last parameter can be ignored as it'll be checked later, if needed
2360 order_direction =
2361
1/2
✓ Branch 0 taken 11617 times.
✗ Branch 1 not taken.
11617 test_if_order_by_key(&order, table, ref_key, &used_key_parts, &dummy);
2362 }
2363
4/4
✓ Branch 0 taken 12453 times.
✓ Branch 1 taken 40320 times.
✓ Branch 2 taken 5475 times.
✓ Branch 3 taken 6978 times.
52773 if (ref_key < 0 || order_direction <= 0) {
2364 /*
2365 There is no ref/index scan/range scan access set up for this
2366 table, or it does not provide the requested ordering, or it uses
2367 backward scan. Do a cost-based search on all keys.
2368 */
2369 45795 uint best_key_parts = 0;
2370 45795 uint saved_best_key_parts = 0;
2371 45795 int best_key_direction = 0;
2372 45795 ha_rows table_records = table->file->stats.records;
2373
2374 /*
2375 If an index scan that cannot provide ordering has been selected
2376 then do not use the index scan key as starting hint to
2377 test_if_cheaper_ordering()
2378 */
2379 const int ref_key_hint =
2380
4/4
✓ Branch 0 taken 43736 times.
✓ Branch 1 taken 2059 times.
✓ Branch 2 taken 42588 times.
✓ Branch 3 taken 1148 times.
45795 (order_direction == 0 && tab->type() == JT_INDEX_SCAN) ? -1 : ref_key;
2381
2382 // Does the query have a "FORCE INDEX [FOR GROUP BY] (idx)" (if clause is
2383 // group by) or a "FORCE INDEX [FOR ORDER BY] (idx)" (if clause is order
2384 // by)?
2385 45795 const bool is_group_by =
2386
4/6
✓ Branch 0 taken 45795 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1047 times.
✓ Branch 3 taken 44748 times.
✓ Branch 4 taken 1047 times.
✗ Branch 5 not taken.
45795 join && join->grouped && order.order == join->group_list.order;
2387 45795 const bool is_force_index =
2388
4/4
✓ Branch 0 taken 45710 times.
✓ Branch 1 taken 85 times.
✓ Branch 2 taken 1031 times.
✓ Branch 3 taken 44679 times.
91505 table->force_index ||
2389
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1029 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 44676 times.
45710 (is_group_by ? table->force_index_group : table->force_index_order);
2390
2391 // Find an ordering index alternative over the chosen plan iff
2392 // prefer_ordering_index switch is on. This switch is overridden only when
2393 // force index for order/group is specified.
2394
6/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 45785 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 45787 times.
✓ Branch 5 taken 8 times.
45795 if (thd->optimizer_switch_flag(OPTIMIZER_SWITCH_PREFER_ORDERING_INDEX) ||
2395 is_force_index)
2396
1/2
✓ Branch 0 taken 45787 times.
✗ Branch 1 not taken.
45787 test_if_cheaper_ordering(tab, &order, table, usable_keys, ref_key_hint,
2397 select_limit, &best_key, &best_key_direction,
2398 &select_limit, &best_key_parts,
2399 &saved_best_key_parts);
2400
2401 // Try backward scan for previously found key
2402
4/4
✓ Branch 0 taken 33320 times.
✓ Branch 1 taken 12475 times.
✓ Branch 2 taken 2037 times.
✓ Branch 3 taken 31283 times.
45805 if (best_key < 0 && order_direction < 0) goto check_reverse_order;
2403
2404
2/2
✓ Branch 0 taken 31283 times.
✓ Branch 1 taken 12475 times.
43758 if (best_key < 0) {
2405 // No usable key has been found
2406 31283 can_skip_sorting = false;
2407 31305 goto fix_ICP;
2408 }
2409 /*
2410 If found index will use backward index scan, ref_key uses backward
2411 range/ref, pick the latter as it has better selectivity.
2412 */
2413
4/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 12453 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 12 times.
12475 if (order_direction < 0 && order_direction == best_key_direction) {
2414 10 best_key = -1; // reset found best key
2415 10 goto check_reverse_order;
2416 }
2417
2418 /*
2419 filesort() and join cache are usually faster than reading in
2420 index order and not using join cache. Don't use index scan
2421 unless:
2422 - the user specified FORCE INDEX [FOR {GROUP|ORDER} BY] (have to assume
2423 the user knows what's best)
2424 - the chosen index is clustered primary key (table scan is not cheaper)
2425 */
2426
4/4
✓ Branch 0 taken 9344 times.
✓ Branch 1 taken 3049 times.
✓ Branch 2 taken 8053 times.
✓ Branch 3 taken 1291 times.
21737 if (!is_force_index && (select_limit >= table_records) &&
2427 9344 (tab->type() == JT_ALL &&
2428
6/6
✓ Branch 0 taken 12393 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 78 times.
✓ Branch 3 taken 7975 times.
✓ Branch 4 taken 22 times.
✓ Branch 5 taken 12443 times.
24936 join->primary_tables > join->const_tables + 1) &&
2429
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 19 times.
78 ((unsigned)best_key != table->s->primary_key ||
2430
3/4
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 56 times.
59 !table->file->primary_key_is_clustered())) {
2431 22 can_skip_sorting = false;
2432 22 goto fix_ICP;
2433 }
2434
2435 12443 if (table->quick_keys.is_set(best_key) &&
2436
6/8
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 12340 times.
✓ Branch 2 taken 103 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 103 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 103 times.
✓ Branch 7 taken 12340 times.
12443 !tab->quick_order_tested.is_set(best_key) && best_key != ref_key) {
2437 103 tab->quick_order_tested.set_bit(best_key);
2438
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
103 Opt_trace_object trace_wrapper_3(trace);
2439
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
103 Opt_trace_object trace_recest(trace, "rows_estimation");
2440
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
103 trace_recest.add_utf8_table(tab->table_ref)
2441
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
103 .add_utf8("index", table->key_info[best_key].name);
2442
2443
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
103 Key_map keys_to_use; // Force the creation of quick select
2444 103 keys_to_use.set_bit(best_key); // only best_key.
2445 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
2446 103 thd->variables.range_alloc_block_size);
2447 AccessPath *range_scan;
2448
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
206 test_quick_select(
2449 thd, thd->mem_root, &temp_mem_root, keys_to_use, 0,
2450 0, // empty table_map
2451 103 join->calc_found_rows ? HA_POS_ERROR
2452 103 : join->query_expression()->select_limit_cnt,
2453 true, // force quick range
2454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 103 times.
206 order.order->direction, tab->table(), tab->skip_records_in_range(),
2455 103 tab->condition(), &tab->needed_reg, tab->table()->force_index,
2456 103 join->query_block, &range_scan);
2457
6/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 101 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 101 times.
105 if (order_direction < 0 && tab->range_scan() != nullptr &&
2458 2 tab->range_scan() != save_range_scan) {
2459 /*
2460 We came here in case when 3 indexes are available for quick
2461 select:
2462 1 - found by join order optimizer (greedy search) and saved in
2463 save_range_scan
2464 2 - constructed far above, as better suited for order by, but it was
2465 found that it requires backward scan.
2466 3 - constructed right above
2467 In this case we drop quick #2 as #3 is expected to be better.
2468 */
2469 2 destroy(tab->range_scan());
2470 2 tab->set_range_scan(nullptr);
2471 }
2472 /*
2473 If tab->range_scan() pointed to another quick than save_range_scan, we
2474 would lose access to it and leak memory.
2475 */
2476
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 101 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
103 assert(tab->range_scan() == save_range_scan ||
2477 tab->range_scan() == nullptr);
2478 103 tab->set_range_scan(range_scan);
2479
6/6
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 78 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 78 times.
✓ Branch 5 taken 25 times.
103 if (tab->range_scan() && !no_changes)
2480
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 tab->set_type(calc_join_type(tab->range_scan()));
2481 103 }
2482 12443 order_direction = best_key_direction;
2483 /*
2484 saved_best_key_parts is actual number of used keyparts found by the
2485 test_if_order_by_key function. It could differ from keyinfo->key_parts,
2486 thus we have to restore it in case of desc order as it affects
2487 ReverseIndexRangeScanIterator behaviour.
2488 */
2489 12443 used_key_parts =
2490
2/2
✓ Branch 0 taken 1225 times.
✓ Branch 1 taken 11218 times.
12443 (order_direction == -1) ? saved_best_key_parts : best_key_parts;
2491 12443 changed_key = best_key;
2492 // We will use index scan or range scan:
2493 12443 set_up_ref_access_to_key = false;
2494 }
2495
2496 6978 check_reverse_order:
2497
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21468 times.
21468 assert(order_direction != 0);
2498
2499
2/2
✓ Branch 0 taken 3272 times.
✓ Branch 1 taken 18196 times.
21468 if (order_direction == -1) // If ORDER BY ... DESC
2500 {
2501
2/2
✓ Branch 0 taken 1259 times.
✓ Branch 1 taken 2013 times.
3272 if (tab->range_scan()) {
2502 /*
2503 Don't reverse the sort order, if it's already done.
2504 (In some cases test_if_order_by_key() can be called multiple times
2505 */
2506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1259 times.
1259 if (is_reverse_sorted_range(tab->range_scan())) {
2507 can_skip_sorting = true;
2508 goto fix_ICP;
2509 }
2510 // test_if_cheaper_ordering() might disable range scan on current index
2511
5/6
✓ Branch 0 taken 1253 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1253 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1253 times.
✓ Branch 5 taken 6 times.
2512 if (tab->table()->quick_keys.is_set(used_index(tab->range_scan())) &&
2512 1253 reverse_sort_possible(tab->range_scan()))
2513 1253 can_skip_sorting = true;
2514 else {
2515 6 can_skip_sorting = false;
2516 6 goto fix_ICP;
2517 }
2518 } else {
2519 // Other index access (ref or scan) poses no problem
2520 2013 can_skip_sorting = true;
2521 }
2522 } else {
2523 // ORDER BY ASC poses no problem
2524 18196 can_skip_sorting = true;
2525 }
2526
2527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21462 times.
21462 assert(can_skip_sorting);
2528
2529 /*
2530 Update query plan with access pattern for doing
2531 ordered access according to what we have decided
2532 above.
2533 */
2534
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 21408 times.
21462 if (!no_changes) // We are allowed to update QEP
2535 {
2536
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 21089 times.
21408 if (set_up_ref_access_to_key) {
2537 /*
2538 We'll use ref access method on key changed_key. In general case
2539 the index search tuple for changed_ref_key will be different (e.g.
2540 when one index is defined as (part1, part2, ...) and another as
2541 (part1, part2(N), ...) and the WHERE clause contains
2542 "part1 = const1 AND part2=const2".
2543 So we build tab->ref() from scratch here.
2544 */
2545 319 Key_use *keyuse = tab->keyuse();
2546
2/2
✓ Branch 0 taken 303 times.
✓ Branch 1 taken 319 times.
622 while (keyuse->key != (uint)changed_key &&
2547
1/2
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
303 keyuse->table_ref == tab->table_ref)
2548 303 keyuse++;
2549
2550
2/4
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 319 times.
319 if (create_ref_for_key(join, tab, keyuse, tab->prefix_tables())) {
2551 can_skip_sorting = false;
2552 goto fix_ICP;
2553 }
2554
2555
2/4
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 319 times.
✗ Branch 3 not taken.
319 assert(tab->type() != JT_REF_OR_NULL && tab->type() != JT_FT);
2556
2557 // Changing the key makes filter_effect obsolete
2558 319 tab->position()->filter_effect = COND_FILTER_STALE;
2559
2560 /*
2561 Check if it is possible to shift from ref to range. The index chosen
2562 for 'ref' has changed since the last time this function was called.
2563 */
2564
3/4
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 303 times.
319 if (can_switch_from_ref_to_range(thd, tab, order.order->direction,
2565 true)) {
2566 // Allow the code to fall-through to the next if condition.
2567 16 set_up_ref_access_to_key = false;
2568 16 best_key = changed_key;
2569 }
2570 }
2571
4/4
✓ Branch 0 taken 21105 times.
✓ Branch 1 taken 303 times.
✓ Branch 2 taken 12449 times.
✓ Branch 3 taken 8656 times.
21408 if (!set_up_ref_access_to_key && best_key >= 0) {
2572 // Cancel any ref-access previously set up
2573 12449 tab->ref().key = -1;
2574 12449 tab->ref().key_parts = 0;
2575
2576 /*
2577 If ref_key used index tree reading only ('Using index' in EXPLAIN),
2578 and best_key doesn't, then revert the decision.
2579 */
2580
3/4
✓ Branch 0 taken 12373 times.
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 12373 times.
✗ Branch 3 not taken.
12449 if (!table->covering_keys.is_set(best_key)) table->set_keyread(false);
2581 // Create an index scan if the table is not a temporary table that uses
2582 // Temptable engine (Does not support index_first() and index_last()) and
2583 // if there was no new range scan created.
2584 12449 if (!(is_temporary_table(tab->table_ref) &&
2585
8/10
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 12370 times.
✓ Branch 2 taken 79 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 79 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 639 times.
✓ Branch 7 taken 11810 times.
✓ Branch 8 taken 12355 times.
✓ Branch 9 taken 94 times.
25537 tab->table_ref->table->s->db_type() == temptable_hton) &&
2586
2/2
✓ Branch 0 taken 545 times.
✓ Branch 1 taken 94 times.
13088 ((!tab->range_scan() || tab->range_scan() == save_range_scan))) {
2587 // Avoid memory leak:
2588
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12355 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12355 assert(tab->range_scan() == save_range_scan ||
2589 tab->range_scan() == nullptr);
2590 12355 tab->set_range_scan(nullptr);
2591 12355 tab->set_index(best_key);
2592 12355 tab->set_type(JT_INDEX_SCAN); // Read with index_first(), index_next()
2593 /*
2594 There is a bug. When we change here, e.g. from group_min_max to
2595 index scan: loose index scan expected to read a small number of rows
2596 (jumping through the index), this small number was in
2597 position()->rows_fetched; index scan will read much more, so
2598 rows_fetched should be updated. So should the filtering effect.
2599 It is visible in main.distinct in trunk:
2600 explain SELECT distinct a from t3 order by a desc limit 2;
2601 id select_type table partitions type
2602 possible_keys key key_len ref rows filtered Extra 1
2603 SIMPLE t3 NULL index a a 5 NULL
2604 40 25.00 Using index "rows=40" should be ~200 i.e. # of records
2605 in table. Filter should be 100.00 (no WHERE).
2606 */
2607
1/2
✓ Branch 0 taken 12355 times.
✗ Branch 1 not taken.
12355 table->file->ha_index_or_rnd_end();
2608 12355 tab->position()->filter_effect = COND_FILTER_STALE;
2609
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 } else if (tab->type() != JT_ALL) {
2610 /*
2611 We're about to use a quick access to the table.
2612 We need to change the access method so as the quick access
2613 method is actually used.
2614 */
2615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 assert(tab->range_scan());
2616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 assert(used_index(tab->range_scan()) == (uint)best_key);
2617
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 tab->set_type(calc_join_type(tab->range_scan()));
2618 94 tab->use_quick = QS_RANGE;
2619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 if (is_loose_index_scan(tab->range_scan()))
2620 join->tmp_table_param.precomputed_group_by = true;
2621 94 tab->position()->filter_effect = COND_FILTER_STALE;
2622 }
2623 } // best_key >= 0
2624
2625
2/2
✓ Branch 0 taken 3244 times.
✓ Branch 1 taken 18164 times.
21408 if (order_direction == -1) // If ORDER BY ... DESC
2626 {
2627
2/2
✓ Branch 0 taken 1219 times.
✓ Branch 1 taken 2025 times.
3244 if (tab->range_scan()) {
2628 /* ORDER BY range_key DESC */
2629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1219 times.
1219 if (make_reverse(used_key_parts, tab->range_scan())) {
2630 /* purecov: begin inspected */
2631 can_skip_sorting = false; // Reverse sort failed -> filesort
2632 goto fix_ICP;
2633 /* purecov: end */
2634 }
2635
1/2
✓ Branch 0 taken 1219 times.
✗ Branch 1 not taken.
1219 tab->set_type(calc_join_type(tab->range_scan()));
2636 1219 tab->position()->filter_effect = COND_FILTER_STALE;
2637
4/4
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 1521 times.
✓ Branch 2 taken 504 times.
✓ Branch 3 taken 1521 times.
2529 } else if (tab->type() == JT_REF &&
2638
1/2
✓ Branch 0 taken 504 times.
✗ Branch 1 not taken.
504 tab->ref().key_parts <= used_key_parts) {
2639 /*
2640 SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
2641
2642 Use a traversal function that starts by reading the last row
2643 with key part (A) and then traverse the index backwards.
2644 */
2645 504 tab->reversed_access = true;
2646
2647 /*
2648 The current implementation of the reverse RefIterator does not
2649 work well in combination with ICP and can lead to increased
2650 execution time. Setting changed_key to the current key
2651 (based on that we change the access order for the key) will
2652 ensure that a pushed index condition will be cancelled.
2653 */
2654 504 changed_key = tab->ref().key;
2655
1/2
✓ Branch 0 taken 1521 times.
✗ Branch 1 not taken.
1521 } else if (tab->type() == JT_INDEX_SCAN)
2656 1521 tab->reversed_access = true;
2657
2/2
✓ Branch 0 taken 3602 times.
✓ Branch 1 taken 14562 times.
18164 } else if (tab->range_scan())
2658 3602 set_need_sorted_output(tab->range_scan());
2659
2660 } // QEP has been modified
2661
2662 54 fix_ICP:
2663 /*
2664 Cleanup:
2665 We may have both a 'tab->range_scan()' and 'save_range_scan' (original)
2666 at this point. Delete the one that we won't use.
2667 */
2668
4/4
✓ Branch 0 taken 21462 times.
✓ Branch 1 taken 31314 times.
✓ Branch 2 taken 21408 times.
✓ Branch 3 taken 54 times.
52776 if (can_skip_sorting && !no_changes) {
2669
4/4
✓ Branch 0 taken 15223 times.
✓ Branch 1 taken 6185 times.
✓ Branch 2 taken 3145 times.
✓ Branch 3 taken 18263 times.
36631 if (tab->type() == JT_INDEX_SCAN &&
2670
2/2
✓ Branch 0 taken 3145 times.
✓ Branch 1 taken 12078 times.
15223 select_limit < table->file->stats.records) {
2671
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3145 times.
3145 assert(select_limit > 0);
2672 3145 tab->position()->rows_fetched = select_limit;
2673 3145 tab->position()->filter_effect = COND_FILTER_STALE_NO_CONST;
2674 }
2675
2676 // Keep current (ordered) tab->range_scan()
2677
2/2
✓ Branch 0 taken 648 times.
✓ Branch 1 taken 20760 times.
21408 if (save_range_scan != tab->range_scan()) destroy(save_range_scan);
2678 } else {
2679 // Restore original save_range_scan
2680
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 31364 times.
31368 if (tab->range_scan() != save_range_scan) {
2681 4 destroy(tab->range_scan());
2682 4 tab->set_range_scan(save_range_scan);
2683 }
2684 }
2685
2686
1/2
✓ Branch 0 taken 52776 times.
✗ Branch 1 not taken.
52776 trace_steps.end();
2687
1/2
✓ Branch 0 taken 52776 times.
✗ Branch 1 not taken.
52776 Opt_trace_object trace_change_index(trace, "index_order_summary");
2688
1/2
✓ Branch 0 taken 52776 times.
✗ Branch 1 not taken.
52776 trace_change_index.add_utf8_table(tab->table_ref)
2689
1/2
✓ Branch 0 taken 52776 times.
✗ Branch 1 not taken.
52776 .add("index_provides_order", can_skip_sorting)
2690
3/4
✓ Branch 0 taken 34580 times.
✓ Branch 1 taken 18196 times.
✓ Branch 2 taken 52776 times.
✗ Branch 3 not taken.
87356 .add_alnum("order_direction",
2691 order_direction == 1
2692 ? "asc"
2693
2/2
✓ Branch 0 taken 3272 times.
✓ Branch 1 taken 31308 times.
34580 : ((order_direction == -1) ? "desc" : "undefined"));
2694
2695
2/2
✓ Branch 0 taken 13289 times.
✓ Branch 1 taken 39487 times.
52776 if (changed_key >= 0) {
2696 // switching to another index
2697 // Should be no pushed index conditions at this point
2698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13289 times.
13289 assert(!table->file->pushed_idx_cond);
2699
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 13249 times.
13289 if (unlikely(trace->is_started())) {
2700
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 trace_change_index.add_utf8("index", table->key_info[changed_key].name);
2701
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 trace_change_index.add("plan_changed", !no_changes);
2702
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 if (!no_changes)
2703
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 trace_change_index.add_alnum("access_type", join_type_str[tab->type()]);
2704 }
2705
2/2
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 39406 times.
39487 } else if (unlikely(trace->is_started())) {
2706
2/4
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✗ Branch 3 not taken.
162 trace_change_index.add_utf8(
2707 81 "index", ref_key >= 0 ? table->key_info[ref_key].name : "unknown");
2708
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
81 trace_change_index.add("plan_changed", false);
2709 }
2710
2/2
✓ Branch 0 taken 40295 times.
✓ Branch 1 taken 12481 times.
52776 *order_idx = best_key < 0 ? ref_key : best_key;
2711 52776 return can_skip_sorting;
2712 313823 }
2713
2714 /**
2715 Prune partitions for all tables of a join (query block).
2716
2717 Requires that tables have been locked.
2718
2719 @returns false if success, true if error
2720 */
2721
2722 83698 bool JOIN::prune_table_partitions() {
2723
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83698 times.
83698 assert(query_block->partitioned_table_count);
2724
2725
2/2
✓ Branch 0 taken 84079 times.
✓ Branch 1 taken 83695 times.
167774 for (TABLE_LIST *tbl = query_block->leaf_tables; tbl; tbl = tbl->next_leaf) {
2726 // This will try to prune non-static conditions, which can be probed after
2727 // the tables are locked.
2728
2729 // Predicates for pruning of this table must be placed in the outer-most
2730 // join nest (Predicates in other join nests, or in the WHERE clause,
2731 // would have caused an outer join to be converted to an inner join,
2732 // and thus there would be no join nest graph to traverse)
2733 // Look up the join nest hierarchy for the outermost condition:
2734 84079 Item *cond = where_cond;
2735 84079 const table_map tbl_map = tbl->map();
2736
2/2
✓ Branch 0 taken 84089 times.
✓ Branch 1 taken 84079 times.
168168 for (TABLE_LIST *nest = tbl; nest != nullptr; nest = nest->embedding) {
2737
6/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 84077 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 84080 times.
84101 if (nest->join_cond_optim() != nullptr &&
2738 12 Overlaps(tbl_map, nest->join_cond_optim()->used_tables())) {
2739 9 cond = nest->join_cond_optim();
2740 // For an anti-join operation, a synthetic left join nest is added above
2741 // the anti-join nest. Make sure that we skip this when searching for
2742 // the predicate to prune.
2743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (nest->is_aj_nest()) break;
2744 }
2745 }
2746
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 84076 times.
84079 if (prune_partitions(thd, tbl->table, query_block, cond)) {
2747 3 return true;
2748 }
2749 }
2750
2751 83695 return false;
2752 }
2753
2754 /**
2755 A helper function to check whether it's better to use range than ref.
2756
2757 @details
2758 Heuristic: Switch from 'ref' to 'range' access if 'range'
2759 access can utilize more keyparts than 'ref' access. Conditions
2760 for doing switching:
2761
2762 1) Range access is possible
2763 2) 'ref' access and 'range' access uses the same index
2764 3) Used parts of key shouldn't have nullable parts & ref_or_null isn't used.
2765 4) 'ref' access depends on a constant, not a value read from a
2766 table earlier in the join sequence.
2767
2768 Rationale: if 'ref' depends on a value from another table,
2769 the join condition is not used to limit the rows read by
2770 'range' access (that would require dynamic range - 'Range
2771 checked for each record'). In other words, if 'ref' depends
2772 on a value from another table, we have a query with
2773 conditions of the form
2774
2775 this_table.idx_col1 = other_table.col AND <<- used by 'ref'
2776 this_table.idx_col1 OP @<const@> AND <<- used by 'range'
2777 this_table.idx_col2 OP @<const@> AND ... <<- used by 'range'
2778
2779 and an index on (idx_col1,idx_col2,...). But the fact that
2780 'range' access uses more keyparts does not mean that it is
2781 more selective than 'ref' access because these access types
2782 utilize different parts of the query condition. We
2783 therefore trust the cost based choice made by
2784 best_access_path() instead of forcing a heuristic choice
2785 here.
2786 5) 'range' access uses more keyparts than 'ref' access
2787 6) ORDER BY might make range better than table scan:
2788 Check possibility of range scan even if it was previously deemed unviable
2789 (for example when table scan was estimated to be cheaper). If yes,
2790 range-access should be chosen only for larger key length.
2791
2792 @param thd To re-run range optimizer.
2793 @param tab JOIN_TAB to check
2794 @param ordering Used as a parameter to call test_quick_select.
2795 @param recheck_range Check possibility of range scan even if it is currently
2796 unviable.
2797
2798 @return true Range is better than ref
2799 @return false Ref is better or switch isn't possible
2800
2801 @todo: This decision should rather be made in best_access_path()
2802 */
2803
2804 1940234 static bool can_switch_from_ref_to_range(THD *thd, JOIN_TAB *tab,
2805 enum_order ordering,
2806 bool recheck_range) {
2807
2/2
✓ Branch 0 taken 4913 times.
✓ Branch 1 taken 95668 times.
2040815 if ((tab->range_scan() && // 1)
2808
6/6
✓ Branch 0 taken 100574 times.
✓ Branch 1 taken 1839724 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 1844318 times.
✓ Branch 4 taken 95987 times.
✓ Branch 5 taken 1844318 times.
2040879 tab->position()->key->key == used_index(tab->range_scan())) || // 2)
2809 recheck_range) {
2810 95987 uint keyparts = 0, length = 0;
2811 95987 table_map dep_map = 0;
2812 95987 bool maybe_null = false;
2813
2814
1/2
✓ Branch 0 taken 95987 times.
✗ Branch 1 not taken.
191974 calc_length_and_keyparts(tab->position()->key, tab,
2815 95987 tab->position()->key->key, tab->prefix_tables(),
2816 nullptr, &length, &keyparts, &dep_map,
2817 &maybe_null);
2818
2/2
✓ Branch 0 taken 95847 times.
✓ Branch 1 taken 140 times.
95987 if (!maybe_null && // 3)
2819
2/2
✓ Branch 0 taken 74072 times.
✓ Branch 1 taken 21775 times.
95847 !dep_map) // 4)
2820 {
2821
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 74043 times.
74072 if (recheck_range) // 6)
2822 {
2823
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 Key_map new_ref_key_map;
2824 29 new_ref_key_map.set_bit(tab->ref().key);
2825
2826 29 Opt_trace_context *const trace = &thd->opt_trace;
2827
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 Opt_trace_object trace_wrapper(trace);
2828 Opt_trace_object can_switch(
2829
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 trace, "check_if_range_uses_more_keyparts_than_ref");
2830 Opt_trace_object trace_cond(
2831
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 trace, "rerunning_range_optimizer_for_single_index");
2832
2833 AccessPath *range_scan;
2834 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
2835 29 thd->variables.range_alloc_block_size);
2836
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
116 if (test_quick_select(
2837 thd, thd->mem_root, &temp_mem_root, new_ref_key_map, 0,
2838 0, // empty table_map
2839 29 tab->join()->row_limit, false, ordering, tab->table(),
2840 29 tab->skip_records_in_range(),
2841 29 tab->join_cond() ? tab->join_cond() : tab->join()->where_cond,
2842 29 &tab->needed_reg, recheck_range, tab->join()->query_block,
2843
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 6 times.
29 &range_scan) > 0) {
2844
3/4
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 7 times.
23 if (length < get_max_used_key_length(range_scan)) {
2845 16 destroy(tab->range_scan());
2846 16 tab->set_range_scan(range_scan);
2847 16 return true;
2848 }
2849
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
14 Opt_trace_object(trace, "access_type_unchanged")
2850 14 .add("ref_key_length", length)
2851
3/6
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 .add("range_key_length", get_max_used_key_length(range_scan));
2852 7 destroy(range_scan);
2853 }
2854
8/8
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 16 times.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 16 times.
77 } else
2855
1/2
✓ Branch 0 taken 74043 times.
✗ Branch 1 not taken.
74043 return length < get_max_used_key_length(tab->range_scan()); // 5)
2856 }
2857 }
2858 1866246 return false;
2859 }
2860
2861 /**
2862 An utility function - apply heuristics and optimize access methods to tables.
2863 Currently this function can change REF to RANGE and ALL to INDEX scan if
2864 latter is considered to be better (not cost-based) than the former.
2865 @note Side effect - this function could set 'Impossible WHERE' zero
2866 result.
2867 */
2868
2869 1767393 void JOIN::adjust_access_methods() {
2870
3/6
✓ Branch 0 taken 1767402 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1767443 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1767467 times.
✗ Branch 5 not taken.
1767393 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
2871
2/2
✓ Branch 0 taken 6150592 times.
✓ Branch 1 taken 1767540 times.
7918132 for (uint i = const_tables; i < tables; i++) {
2872 6150592 JOIN_TAB *const tab = best_ref[i];
2873 6150592 TABLE_LIST *const tl = tab->table_ref;
2874
2875
2/2
✓ Branch 0 taken 1842452 times.
✓ Branch 1 taken 4308215 times.
6150592 if (tab->type() == JT_ALL) {
2876 /*
2877 It's possible to speedup query by switching from full table scan to
2878 the scan of covering index, due to less data being read.
2879 Prerequisites for this are:
2880 1) Keyread (i.e index only scan) is allowed (table isn't updated/deleted
2881 from)
2882 2) Covering indexes are available
2883 3) This isn't a derived table/materialized view
2884 */
2885 1842452 if (!tab->table()->no_keyread && // 1
2886
6/6
✓ Branch 0 taken 1784623 times.
✓ Branch 1 taken 57849 times.
✓ Branch 2 taken 407814 times.
✓ Branch 3 taken 1376826 times.
✓ Branch 4 taken 407683 times.
✓ Branch 5 taken 1434817 times.
2250297 !tab->table()->covering_keys.is_clear_all() && // 2
2887
2/2
✓ Branch 0 taken 407675 times.
✓ Branch 1 taken 150 times.
407814 !tl->uses_materialization()) // 3
2888 {
2889 /*
2890 It has turned out that the change commented out below, while speeding
2891 things up for disk-bound loads, slows them down for cases when the data
2892 is in disk cache (see BUG#35850):
2893 // See bug #26447: "Using the clustered index for a table scan
2894 // is always faster than using a secondary index".
2895 if (table->s->primary_key != MAX_KEY &&
2896 table->file->primary_key_is_clustered())
2897 tab->index= table->s->primary_key;
2898 else
2899 tab->index=find_shortest_key(table, & table->covering_keys);
2900 */
2901
2/2
✓ Branch 0 taken 407461 times.
✓ Branch 1 taken 221 times.
407683 if (tab->position()->sj_strategy != SJ_OPT_LOOSE_SCAN)
2902 407470 tab->set_index(
2903 407461 find_shortest_key(tab->table(), &tab->table()->covering_keys));
2904 407653 tab->set_type(JT_INDEX_SCAN); // Read with index_first / index_next
2905 // From table scan to index scan, thus filter effect needs no recalc.
2906
6/6
✓ Branch 0 taken 1376961 times.
✓ Branch 1 taken 57864 times.
✓ Branch 2 taken 1201897 times.
✓ Branch 3 taken 175064 times.
✓ Branch 4 taken 1201897 times.
✓ Branch 5 taken 232928 times.
1434817 } else if (!tab->table()->no_keyread && !tl->uses_materialization()) {
2907
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1201897 times.
1201897 assert(tab->table()->covering_keys.is_clear_all());
2908
1/2
✓ Branch 0 taken 1201897 times.
✗ Branch 1 not taken.
1201897 if (tab->position()->sj_strategy != SJ_OPT_LOOSE_SCAN) {
2909
1/2
✓ Branch 0 taken 1201897 times.
✗ Branch 1 not taken.
1201897 Key_map clustering_keys;
2910
2/2
✓ Branch 0 taken 1432720 times.
✓ Branch 1 taken 1201897 times.
2634617 for (uint i2 = 0; i2 < tab->table()->s->keys; i2++) {
2911
3/4
✓ Branch 0 taken 603312 times.
✓ Branch 1 taken 829408 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1432720 times.
2036032 if (tab->keys().is_set(i2) &&
2912
2/4
✓ Branch 0 taken 603312 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 603312 times.
603312 tab->table()->file->index_flags(i2, 0, 0) & HA_CLUSTERED_INDEX)
2913 clustering_keys.set_bit(i2);
2914 }
2915
1/2
✓ Branch 0 taken 1201897 times.
✗ Branch 1 not taken.
1201897 uint index = find_shortest_key(tab->table(), &clustering_keys);
2916
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1201897 times.
1201897 if (index != MAX_KEY) {
2917 tab->set_type(JT_INDEX_SCAN);
2918 tab->set_index(index);
2919 }
2920 }
2921 }
2922
2/2
✓ Branch 0 taken 1939989 times.
✓ Branch 1 taken 2368239 times.
4308215 } else if (tab->type() == JT_REF) {
2923
2/2
✓ Branch 0 taken 1017 times.
✓ Branch 1 taken 1938898 times.
1939989 if (can_switch_from_ref_to_range(thd, tab, ORDER_NOT_RELEVANT, false)) {
2924 1017 tab->set_type(JT_RANGE);
2925
2926 1017 Opt_trace_context *const trace = &thd->opt_trace;
2927
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 Opt_trace_object wrapper(trace);
2928
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
2034 Opt_trace_object(trace, "access_type_changed")
2929
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 .add_utf8_table(tl)
2930 2034 .add_utf8("index",
2931
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 tab->table()->key_info[tab->position()->key->key].name)
2932
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 .add_alnum("old_type", "ref")
2933
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 .add_alnum("new_type", join_type_str[tab->type()])
2934
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 .add_alnum("cause", "uses_more_keyparts");
2935
2936 1017 tab->use_quick = QS_RANGE;
2937 1017 tab->position()->filter_effect = COND_FILTER_STALE;
2938 1017 } else {
2939 // Cleanup quick, REF/REF_OR_NULL/EQ_REF, will be clarified later
2940 1938898 ::destroy(tab->range_scan());
2941 1938899 tab->set_range_scan(nullptr);
2942 }
2943 }
2944 // Ensure AM consistency
2945
4/6
✓ Branch 0 taken 33913 times.
✓ Branch 1 taken 6116804 times.
✓ Branch 2 taken 33913 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33913 times.
✗ Branch 5 not taken.
6150688 assert(!(tab->range_scan() &&
2946 (tab->type() == JT_REF || tab->type() == JT_ALL)));
2947
5/6
✓ Branch 0 taken 6117708 times.
✓ Branch 1 taken 33044 times.
✓ Branch 2 taken 6116842 times.
✓ Branch 3 taken 866 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 33913 times.
6150717 assert((tab->type() != JT_RANGE && tab->type() != JT_INDEX_MERGE) ||
2948 tab->range_scan());
2949 6150755 if (!tab->const_keys.is_clear_all() &&
2950
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 454701 times.
454744 tab->table()->reginfo.impossible_range &&
2951
5/6
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 34 times.
86 ((i == const_tables && tab->type() == JT_REF) ||
2952
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
61 ((tab->type() == JT_ALL || tab->type() == JT_RANGE ||
2953
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
18 tab->type() == JT_INDEX_MERGE || tab->type() == JT_INDEX_SCAN) &&
2954
5/6
✓ Branch 0 taken 454744 times.
✓ Branch 1 taken 5696003 times.
✓ Branch 2 taken 110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37 times.
✓ Branch 5 taken 6150637 times.
6605528 tab->use_quick != QS_RANGE)) &&
2955
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
110 !tab->table_ref->is_inner_table_of_outer_join())
2956 37 zero_result_cause = "Impossible WHERE noticed after reading const tables";
2957 }
2958 1767540 }
2959
2960 3733737 static JOIN_TAB *alloc_jtab_array(THD *thd, uint table_count) {
2961
5/8
✓ Branch 0 taken 3733772 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3733815 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6405536 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6405487 times.
✓ Branch 7 taken 3733864 times.
10139224 JOIN_TAB *t = new (thd->mem_root) JOIN_TAB[table_count];
2962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3733862 times.
3733862 if (!t) return nullptr; /* purecov: inspected */
2963
2964
5/8
✓ Branch 0 taken 3733872 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3733846 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6405298 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6405328 times.
✓ Branch 7 taken 3733816 times.
10139160 QEP_shared *qs = new (thd->mem_root) QEP_shared[table_count];
2965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3733816 times.
3733816 if (!qs) return nullptr; /* purecov: inspected */
2966
2967
2/2
✓ Branch 0 taken 6405460 times.
✓ Branch 1 taken 3733791 times.
10139251 for (uint i = 0; i < table_count; ++i) t[i].set_qs(qs++);
2968
2969 3733791 return t;
2970 }
2971
2972 /**
2973 Set up JOIN_TAB structs according to the picked join order in best_positions.
2974 This allocates execution structures so may be called only after we have the
2975 very final plan. It must be called after
2976 Optimize_table_order::fix_semijoin_strategies().
2977
2978 @return False if success, True if error
2979
2980 @details
2981 - create join->join_tab array and copy from existing JOIN_TABs in join order
2982 - create helper structs for materialized semi-join handling
2983 - finalize semi-join strategy choices
2984 - Number of intermediate tables "tmp_tables" is calculated.
2985 - "tables" and "primary_tables" are recalculated.
2986 - for full and index scans info of estimated # of records is updated.
2987 - in a helper function:
2988 - all heuristics are applied and the final access method type is picked
2989 for each join_tab (only test_if_skip_sortorder() could override it)
2990 - AM consistency is ensured (e.g only range and index merge are allowed
2991 to have quick select set).
2992 - if "Impossible WHERE" is detected - appropriate zero_result_cause is
2993 set.
2994
2995 Notice that intermediate tables will not have a POSITION reference; and they
2996 will not have a TABLE reference before the final stages of code generation.
2997
2998 @todo the block which sets tab->type should move to adjust_access_methods
2999 for unification.
3000 */
3001
3002 1866783 bool JOIN::get_best_combination() {
3003
1/2
✓ Branch 0 taken 1866878 times.
✗ Branch 1 not taken.
1866783 DBUG_TRACE;
3004
3005 // At this point "tables" and "primary"tables" represent the same:
3006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1866878 times.
1866878 assert(tables == primary_tables);
3007
3008 /*
3009 Allocate additional space for tmp tables.
3010 Number of plan nodes:
3011 # of regular input tables (including semi-joined ones) +
3012 # of semi-join nests for materialization +
3013 1? + // For GROUP BY (or implicit grouping when we have windowing)
3014 1? + // For DISTINCT
3015 1? + // For aggregation functions aggregated in outer query
3016 // when used with distinct
3017 1? + // For ORDER BY
3018 1? // buffer result
3019
3020 Up to 2 tmp tables + N window output tmp are allocated (NOTE: windows also
3021 have frame buffer tmp tables, but those are not relevant here).
3022 */
3023 uint num_tmp_tables =
3024
4/4
✓ Branch 0 taken 339347 times.
✓ Branch 1 taken 1503922 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 339305 times.
3710147 (!group_list.empty() || (implicit_grouping && m_windows.elements > 0)
3025
2/2
✓ Branch 0 taken 1843269 times.
✓ Branch 1 taken 23550 times.
3710088 ? 1
3026 1866819 : 0) +
3027
4/4
✓ Branch 0 taken 4213 times.
✓ Branch 1 taken 1862606 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 4171 times.
1866819 (select_distinct ? (tmp_table_param.outer_sum_func_count ? 2 : 1) : 0) +
3028
2/2
✓ Branch 0 taken 1315389 times.
✓ Branch 1 taken 551430 times.
1866819 (order.empty() ? 0 : 1) +
3029 1866819 (query_block->active_options() &
3030 (SELECT_BIG_RESULT | OPTION_BUFFER_RESULT)
3031
2/2
✓ Branch 0 taken 5771 times.
✓ Branch 1 taken 1861062 times.
1866833 ? 1
3032 1866833 : 0) +
3033 1866833 m_windows.elements + 1; /* the presence of windows may increase need for
3034 grouping tmp tables, cf. de-optimization
3035 in make_tmp_tables_info
3036 */
3037
2/2
✓ Branch 0 taken 4900 times.
✓ Branch 1 taken 1861933 times.
1866833 if (num_tmp_tables > (2 + m_windows.elements))
3038 4900 num_tmp_tables = 2 + m_windows.elements;
3039
3040 /*
3041 Rearrange queries with materialized semi-join nests so that the semi-join
3042 nest is replaced with a reference to a materialized temporary table and all
3043 materialized subquery tables are placed after the intermediate tables.
3044 After the following loop, "inner_target" is the position of the first
3045 subquery table (if any). "outer_target" is the position of first outer
3046 table, and will later be used to track the position of any materialized
3047 temporary tables.
3048 */
3049
1/2
✓ Branch 0 taken 1866865 times.
✗ Branch 1 not taken.
1866833 const bool has_semijoin = !query_block->sj_nests.empty();
3050 1866865 uint outer_target = 0;
3051 1866865 uint inner_target = primary_tables + num_tmp_tables;
3052 1866865 uint sjm_nests = 0;
3053
3054
2/2
✓ Branch 0 taken 19226 times.
✓ Branch 1 taken 1847639 times.
1866865 if (has_semijoin) {
3055
2/2
✓ Branch 0 taken 60018 times.
✓ Branch 1 taken 19226 times.
79244 for (uint tableno = 0; tableno < primary_tables;) {
3056
2/2
✓ Branch 0 taken 4591 times.
✓ Branch 1 taken 55427 times.
60018 if (sj_is_materialize_strategy(best_positions[tableno].sj_strategy)) {
3057 4591 sjm_nests++;
3058 4591 inner_target -= (best_positions[tableno].n_sj_tables - 1);
3059 4591 tableno += best_positions[tableno].n_sj_tables;
3060 } else
3061 55427 tableno++;
3062 }
3063 }
3064
3065 1866865 JOIN_TAB *tmp_join_tabs = nullptr;
3066
2/2
✓ Branch 0 taken 1866811 times.
✓ Branch 1 taken 54 times.
1866865 if (sjm_nests + num_tmp_tables) {
3067 // join_tab array only has "primary_tables" tables. We need those more:
3068
2/4
✓ Branch 0 taken 1866867 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1866867 times.
1866811 if (!(tmp_join_tabs = alloc_jtab_array(thd, sjm_nests + num_tmp_tables)))
3069 return true; /* purecov: inspected */
3070 }
3071
3072 // To check that we fill the array correctly: fill it with zeros first
3073 1866921 memset(best_ref, 0,
3074 1866921 sizeof(JOIN_TAB *) * (primary_tables + sjm_nests + num_tmp_tables));
3075
3076 1866921 int sjm_index = tables; // Number assigned to materialized temporary table
3077 1866921 int remaining_sjm_inner = 0;
3078 1866921 bool err = false;
3079
2/2
✓ Branch 0 taken 3951136 times.
✓ Branch 1 taken 1867022 times.
5818158 for (uint tableno = 0; tableno < tables; tableno++) {
3080 3951136 POSITION *const pos = best_positions + tableno;
3081
6/6
✓ Branch 0 taken 63886 times.
✓ Branch 1 taken 3887250 times.
✓ Branch 2 taken 4591 times.
✓ Branch 3 taken 59295 times.
✓ Branch 4 taken 4591 times.
✓ Branch 5 taken 3946545 times.
3951136 if (has_semijoin && sj_is_materialize_strategy(pos->sj_strategy)) {
3082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4591 times.
4591 assert(outer_target < inner_target);
3083
3084 4591 TABLE_LIST *const sj_nest = pos->table->emb_sj_nest;
3085
3086 // Handle this many inner tables of materialized semi-join
3087 4591 remaining_sjm_inner = pos->n_sj_tables;
3088
3089 /*
3090 If we fail in some allocation below, we cannot bail out immediately;
3091 that would put us in a difficult situation to clean up; imagine we
3092 have planned this layout:
3093 outer1 - sj_mat_tmp1 - outer2 - sj_mat_tmp2 - outer3
3094 We have successfully filled a JOIN_TAB for sj_mat_tmp1, and are
3095 failing to fill a JOIN_TAB for sj_mat_tmp2 (OOM). So we want to quit
3096 this function, which will lead to cleanup functions.
3097 But sj_mat_tmp1 is in this->best_ref only, outer3 is in this->join_tab
3098 only: what is the array to traverse for cleaning up? What is the
3099 number of tables to loop over?
3100 So: if we fail in the present loop, we record the error but continue
3101 filling best_ref; when it's fully filled, bail out, because then
3102 best_ref can be used as reliable array for cleaning up.
3103 */
3104 4591 JOIN_TAB *const tab = tmp_join_tabs++;
3105 4591 best_ref[outer_target] = tab;
3106 4591 tab->set_join(this);
3107 4591 tab->set_idx(outer_target);
3108
3109 /*
3110 Up to this point there cannot be a failure. JOIN_TAB has been filled
3111 enough to be clean-able.
3112 */
3113
3114 4591 Semijoin_mat_exec *const sjm_exec = new (thd->mem_root) Semijoin_mat_exec(
3115 4591 sj_nest, (pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN),
3116
2/4
✓ Branch 0 taken 4591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4591 times.
✗ Branch 3 not taken.
4591 remaining_sjm_inner, outer_target, inner_target);
3117
3118 4591 tab->set_sj_mat_exec(sjm_exec);
3119
3120
3/6
✓ Branch 0 taken 4591 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4591 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4591 times.
9182 if (!sjm_exec || setup_semijoin_materialized_table(
3121
1/2
✓ Branch 0 taken 4591 times.
✗ Branch 1 not taken.
4591 tab, sjm_index, pos, best_positions + sjm_index))
3122 err = true; /* purecov: inspected */
3123
3124 4591 outer_target++;
3125 4591 sjm_index++;
3126 }
3127 /*
3128 Locate join_tab target for the table we are considering.
3129 (remaining_sjm_inner becomes negative for non-SJM tables, this can be
3130 safely ignored).
3131 */
3132 const uint target =
3133
2/2
✓ Branch 0 taken 8459 times.
✓ Branch 1 taken 3942677 times.
3951136 (remaining_sjm_inner--) > 0 ? inner_target++ : outer_target++;
3134 3951136 JOIN_TAB *const tab = pos->table;
3135
3136 3951136 best_ref[target] = tab;
3137 3951136 tab->set_idx(target);
3138 3951161 tab->set_position(pos);
3139 3951220 TABLE *const table = tab->table();
3140
6/6
✓ Branch 0 taken 3859941 times.
✓ Branch 1 taken 91299 times.
✓ Branch 2 taken 3810844 times.
✓ Branch 3 taken 49108 times.
✓ Branch 4 taken 3810848 times.
✓ Branch 5 taken 140403 times.
3951231 if (tab->type() != JT_CONST && tab->type() != JT_SYSTEM) {
3141
6/6
✓ Branch 0 taken 271 times.
✓ Branch 1 taken 3810577 times.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 200 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 3810804 times.
3810911 if (pos->sj_strategy == SJ_OPT_LOOSE_SCAN && tab->range_scan() &&
3142
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 27 times.
71 used_index(tab->range_scan()) != pos->loosescan_key) {
3143 /*
3144 We must use the duplicate-eliminating index, so this QUICK is not
3145 an option.
3146 */
3147 36 ::destroy(tab->range_scan());
3148 36 tab->set_range_scan(nullptr);
3149 }
3150
2/2
✓ Branch 0 taken 1873325 times.
✓ Branch 1 taken 1937510 times.
3810835 if (!pos->key) {
3151
2/2
✓ Branch 0 taken 32896 times.
✓ Branch 1 taken 1840435 times.
1873325 if (tab->range_scan())
3152
1/2
✓ Branch 0 taken 32896 times.
✗ Branch 1 not taken.
32896 tab->set_type(calc_join_type(tab->range_scan()));
3153 else
3154 1840435 tab->set_type(JT_ALL);
3155 } else
3156 // REF or RANGE, clarify later when prefix tables are set for JOIN_TABs
3157 1937510 tab->set_type(JT_REF);
3158 }
3159
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3951234 times.
3951227 assert(tab->type() != JT_UNKNOWN);
3160
3161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3951234 times.
3951234 assert(table->reginfo.join_tab == tab);
3162
2/2
✓ Branch 0 taken 3424325 times.
✓ Branch 1 taken 526908 times.
3951234 if (!tab->join_cond())
3163 3424325 table->reginfo.not_exists_optimize = false; // Only with LEFT JOIN
3164 3951233 map2table[tab->table_ref->tableno()] = tab;
3165 }
3166
3167 // Count the materialized semi-join tables as regular input tables
3168 1867022 tables += sjm_nests + num_tmp_tables;
3169 // Set the number of non-materialized tables:
3170 1867022 primary_tables = outer_target;
3171
3172 /*
3173 Between the last outer table or sj-mat tmp table, and the first sj-mat
3174 inner table, there may be 2 slots for sort/group/etc tmp tables:
3175 */
3176
2/2
✓ Branch 0 taken 2449542 times.
✓ Branch 1 taken 1867022 times.
4316564 for (uint i = 0; i < num_tmp_tables; ++i) {
3177 2449542 const uint idx = outer_target + i;
3178 2449542 tmp_join_tabs->set_join(this);
3179 2449541 tmp_join_tabs->set_idx(idx);
3180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2449542 times.
2449542 assert(best_ref[idx] == nullptr); // verify that not overwriting
3181 2449542 best_ref[idx] = tmp_join_tabs++;
3182 /*
3183 note that set_table() cannot be called yet. We may not even use this
3184 JOIN_TAB in the end, it's dummy at the moment. Which can be tested with
3185 "position()!=NULL".
3186 */
3187 }
3188
3189 // make array unreachable: should walk JOIN_TABs by best_ref now
3190 1867022 join_tab = nullptr;
3191
3192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1867022 times.
1867022 if (err) return true; /* purecov: inspected */
3193
3194
2/2
✓ Branch 0 taken 19226 times.
✓ Branch 1 taken 1847796 times.
1867022 if (has_semijoin) {
3195
1/2
✓ Branch 0 taken 19226 times.
✗ Branch 1 not taken.
19226 set_semijoin_info();
3196
3197 // Update equalities and keyuses after having added SJ materialization
3198
2/4
✓ Branch 0 taken 19226 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19226 times.
19226 if (update_equalities_for_sjm()) return true;
3199 }
3200
2/2
✓ Branch 0 taken 1767452 times.
✓ Branch 1 taken 99394 times.
1867022 if (!plan_is_const()) {
3201 // Assign map of "available" tables to all tables belonging to query block
3202
1/2
✓ Branch 0 taken 1767481 times.
✗ Branch 1 not taken.
1767452 set_prefix_tables();
3203
1/2
✓ Branch 0 taken 1767483 times.
✗ Branch 1 not taken.
1767481 adjust_access_methods();
3204 }
3205 // Calculate outer join info
3206
3/4
✓ Branch 0 taken 195268 times.
✓ Branch 1 taken 1671609 times.
✓ Branch 2 taken 195259 times.
✗ Branch 3 not taken.
1866877 if (query_block->outer_join) make_outerjoin_info();
3207
3208 // sjm is no longer needed, trash it. To reuse it, reset its members!
3209
7/12
✓ Branch 0 taken 1866882 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1866884 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19861 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 19861 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1886743 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 19861 times.
✓ Branch 11 taken 1866882 times.
1886729 for (TABLE_LIST *sj_nest : query_block->sj_nests) {
3210 19861 TRASH(static_cast<void *>(&sj_nest->nested_join->sjm),
3211 sizeof(sj_nest->nested_join->sjm));
3212 }
3213
3214 1866882 return false;
3215 1866882 }
3216
3217 /**
3218 Finds the dependencies of the remaining lateral derived tables.
3219
3220 @param plan_tables map of all tables that the planner is processing
3221 (tables already in plan and tables to be added to plan).
3222 @param idx index of the table which the planner is currently
3223 considering.
3224 @return A map of the dependencies of the remaining
3225 lateral derived tables (from best_ref[idx] and on).
3226 */
3227 7598 table_map JOIN::calculate_deps_of_remaining_lateral_derived_tables(
3228 table_map plan_tables, uint idx) const {
3229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7598 times.
7598 assert(has_lateral);
3230 7598 table_map deps = 0;
3231 7598 auto last = best_ref + tables;
3232
2/2
✓ Branch 0 taken 26548 times.
✓ Branch 1 taken 7598 times.
34146 for (auto **pos = best_ref + idx; pos < last; pos++) {
3233
6/6
✓ Branch 0 taken 25885 times.
✓ Branch 1 taken 663 times.
✓ Branch 2 taken 25876 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 25876 times.
✓ Branch 5 taken 672 times.
26548 if ((*pos)->table_ref && ((*pos)->table_ref->map() & plan_tables)) {
3234 25876 deps |= get_lateral_deps(**pos);
3235 }
3236 }
3237 7598 return deps;
3238 }
3239
3240 /*
3241 Revise usage of join buffer for the specified table and the whole nest
3242
3243 SYNOPSIS
3244 revise_cache_usage()
3245 tab join table for which join buffer usage is to be revised
3246
3247 DESCRIPTION
3248 The function revise the decision to use a join buffer for the table 'tab'.
3249 If this table happened to be among the inner tables of a nested outer join/
3250 semi-join the functions denies usage of join buffers for all of them
3251
3252 RETURN
3253 none
3254 */
3255
3256 1915684 static void revise_cache_usage(JOIN_TAB *join_tab) {
3257 1915684 plan_idx first_inner = join_tab->first_inner();
3258 1915731 JOIN *const join = join_tab->join();
3259
2/2
✓ Branch 0 taken 522899 times.
✓ Branch 1 taken 1392850 times.
1915749 if (first_inner != NO_PLAN_IDX) {
3260 522899 plan_idx end_tab = join_tab->idx();
3261
2/2
✓ Branch 0 taken 523459 times.
✓ Branch 1 taken 522900 times.
1046350 for (first_inner = join_tab->first_inner(); first_inner != NO_PLAN_IDX;
3262 523459 first_inner = join->best_ref[first_inner]->first_upper()) {
3263
2/2
✓ Branch 0 taken 4825 times.
✓ Branch 1 taken 523459 times.
528284 for (plan_idx i = end_tab - 1; i >= first_inner; --i)
3264 4825 join->best_ref[i]->set_use_join_cache(JOIN_CACHE::ALG_NONE);
3265 523459 end_tab = first_inner;
3266 }
3267
2/2
✓ Branch 0 taken 7533 times.
✓ Branch 1 taken 1385274 times.
1392850 } else if (join_tab->get_sj_strategy() == SJ_OPT_FIRST_MATCH) {
3268 7533 plan_idx first_sj_inner = join_tab->first_sj_inner();
3269
2/2
✓ Branch 0 taken 4832 times.
✓ Branch 1 taken 7533 times.
12365 for (plan_idx i = join_tab->idx() - 1; i >= first_sj_inner; --i) {
3270 4832 JOIN_TAB *tab = join->best_ref[i];
3271
1/2
✓ Branch 0 taken 4832 times.
✗ Branch 1 not taken.
4832 if (tab->first_sj_inner() == first_sj_inner)
3272 4832 tab->set_use_join_cache(JOIN_CACHE::ALG_NONE);
3273 }
3274 } else
3275 1385274 join_tab->set_use_join_cache(JOIN_CACHE::ALG_NONE);
3276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1915675 times.
1915675 assert(join->qep_tab == nullptr);
3277 1915675 }
3278
3279 /**
3280 Set up join buffering for a specified table, if possible.
3281
3282 @param tab joined table to check join buffer usage for
3283 @param join join for which the check is performed
3284 @param no_jbuf_after don't use join buffering after table with this number
3285
3286 @return false if successful, true if error.
3287 Currently, allocation errors for join cache objects are ignored,
3288 and regular execution is chosen silently.
3289
3290 @details
3291 The function finds out whether the table 'tab' can be joined using a join
3292 buffer. This check is performed after the best execution plan for 'join'
3293 has been chosen. If the function decides that a join buffer can be employed
3294 then it selects the most appropriate join cache type, which later will
3295 be instantiated by init_join_cache().
3296 If it has already been decided to not use join buffering for this table,
3297 no action is taken.
3298
3299 Often it is already decided that join buffering will be used earlier in
3300 the optimization process, and this will also ensure that the most correct
3301 cost for the operation is calculated, and hence the probability of
3302 choosing an optimal join plan is higher. However, some join buffering
3303 decisions cannot currently be taken before this stage, hence we need this
3304 function to decide the most accurate join buffering strategy.
3305
3306 @todo Long-term it is the goal that join buffering strategy is decided
3307 when the plan is selected.
3308
3309 The result of the check and the type of the join buffer to be used
3310 depend on:
3311 - the access method to access rows of the joined table
3312 - whether the join table is an inner table of an outer join or semi-join
3313 - the optimizer_switch settings for join buffering
3314 - the join 'options'.
3315 In any case join buffer is not used if the number of the joined table is
3316 greater than 'no_jbuf_after'.
3317
3318 If block_nested_loop is turned on, and if all other criteria for using
3319 join buffering is fulfilled (see below), then join buffer is used
3320 for any join operation (inner join, outer join, semi-join) with 'JT_ALL'
3321 access method. In that case, a JOIN_CACHE_BNL type is always employed.
3322
3323 If an index is used to access rows of the joined table and
3324 batched_key_access is on, then a JOIN_CACHE_BKA type is employed.
3325
3326 If the function decides that a join buffer can be used to join the table
3327 'tab' then it sets @c tab->use_join_cache to reflect the chosen algorithm.
3328
3329 @note
3330 For a nested outer join/semi-join, currently, we either use join buffers for
3331 all inner tables or for none of them.
3332
3333 Join buffering is enabled for a few more cases for secondary engine.
3334 Currently if blocked nested loop(BNL) is employed for join buffering,
3335 it is replaced by hash joins in the executor. So the reasons for disabling
3336 join buffering because of the way BNL works are no more valid. This gives
3337 us an oppotunity to enable join buffering for more cases. However,
3338 we enable it only for secondary engine (in particular for semijoins),
3339 because of the following reasons:
3340 Secondary engine does not care about the cost based decisions
3341 involved in arriving at the best possible semijoin strategy;
3342 because it can only interpret a plan using "FirstMatch" strategy
3343 and can only do table scans. So the choices are very limited.
3344 However, it's not the case for mysql. There are serveral semijoin
3345 stratagies that could be picked. And these are picked based
3346 on the assumption that a nested-loop join(NLJ) would be used because
3347 optimizer currently generates plans only for NLJs and not
3348 hash joins. So, when executor replaces with hash joins, the number
3349 of rows that would be looked into for a particular semijoin strategy
3350 will differ from what the optimizer presumed while picking that
3351 strategy.
3352 For mysql server, we could enable join buffering for more cases, when
3353 a cost model for using hash joins is developed and optimizer could
3354 generate plans for hash joins.
3355
3356 @todo
3357 Support BKA inside SJ-Materialization nests. When doing this, we'll need
3358 to only store sj-inner tables in the join buffer.
3359 @verbatim
3360 JOIN_TAB *first_tab= join->join_tab+join->const_tables;
3361 uint n_tables= i-join->const_tables;
3362 / *
3363 We normally put all preceding tables into the join buffer, except
3364 for the constant tables.
3365 If we're inside a semi-join materialization nest, e.g.
3366
3367 outer_tbl1 outer_tbl2 ( inner_tbl1, inner_tbl2 ) ...
3368 ^-- we're here
3369
3370 then we need to put into the join buffer only the tables from
3371 within the nest.
3372 * /
3373 if (i >= first_sjm_table && i < last_sjm_table)
3374 {
3375 n_tables= i - first_sjm_table; // will be >0 if we got here
3376 first_tab= join->join_tab + first_sjm_table;
3377 }
3378 @endverbatim
3379 */
3380
3381 3778391 static bool setup_join_buffering(JOIN_TAB *tab, JOIN *join,
3382 uint no_jbuf_after) {
3383
3/6
✓ Branch 0 taken 3778459 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3778508 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3778525 times.
✗ Branch 5 not taken.
3778391 ASSERT_BEST_REF_IN_JOIN_ORDER(join);
3384 3778457 Cost_estimate cost;
3385 ha_rows rows;
3386 3778499 uint bufsz = 4096;
3387 3778499 uint join_cache_flags = 0;
3388
1/2
✓ Branch 0 taken 3778507 times.
✗ Branch 1 not taken.
3778499 const bool bnl_on = hint_table_state(join->thd, tab->table_ref, BNL_HINT_ENUM,
3389 OPTIMIZER_SWITCH_BNL);
3390
1/2
✓ Branch 0 taken 3778540 times.
✗ Branch 1 not taken.
3778507 const bool bka_on = hint_table_state(join->thd, tab->table_ref, BKA_HINT_ENUM,
3391 OPTIMIZER_SWITCH_BKA);
3392
3393 3778540 const uint tableno = tab->idx();
3394
1/2
✓ Branch 0 taken 3778552 times.
✗ Branch 1 not taken.
3778532 const uint tab_sj_strategy = tab->get_sj_strategy();
3395
3396 /*
3397 If all key_parts are null_rejecting, the MultiRangeRowIterator will
3398 eliminate all NULL values in the key set, such that
3399 HA_MRR_NO_NULL_ENDPOINTS can be promised.
3400 */
3401 3778552 const key_part_map keypart_map = make_prev_keypart_map(tab->ref().key_parts);
3402
2/2
✓ Branch 0 taken 2367587 times.
✓ Branch 1 taken 1410951 times.
3778551 if (tab->ref().null_rejecting == keypart_map) {
3403 2367587 join_cache_flags |= HA_MRR_NO_NULL_ENDPOINTS;
3404 }
3405
3406 // Set preliminary join cache setting based on decision from greedy search
3407
2/2
✓ Branch 0 taken 3762583 times.
✓ Branch 1 taken 15955 times.
3778538 if (!join->select_count)
3408
2/2
✓ Branch 0 taken 156776 times.
✓ Branch 1 taken 3605812 times.
3762583 tab->set_use_join_cache(tab->position()->use_join_buffer
3409 ? JOIN_CACHE::ALG_BNL
3410 : JOIN_CACHE::ALG_NONE);
3411
3412
2/2
✓ Branch 0 taken 1730973 times.
✓ Branch 1 taken 2047553 times.
3778526 if (tableno == join->const_tables) {
3413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1730953 times.
1730973 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3414 1730953 return false;
3415 }
3416
3417
4/4
✓ Branch 0 taken 16789 times.
✓ Branch 1 taken 2030764 times.
✓ Branch 2 taken 616 times.
✓ Branch 3 taken 16173 times.
2047553 if (!(bnl_on || bka_on)) goto no_join_cache;
3418
3419 /*
3420 psergey-todo: why the below when execution code seems to handle the
3421 "range checked for each record" case?
3422 */
3423
2/2
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 2046418 times.
2046937 if (tab->use_quick == QS_DYNAMIC_RANGE) goto no_join_cache;
3424
3425 /* No join buffering if prevented by no_jbuf_after */
3426
2/2
✓ Branch 0 taken 27683 times.
✓ Branch 1 taken 2018735 times.
2046418 if (tableno > no_jbuf_after) goto no_join_cache;
3427
3428 /*
3429 An inner table of an outer join nest must not use join buffering if
3430 the first inner table of that outer join nest does not use join buffering.
3431 This condition is not handled by earlier optimizer stages.
3432 */
3433
8/8
✓ Branch 0 taken 532547 times.
✓ Branch 1 taken 1486189 times.
✓ Branch 2 taken 2962 times.
✓ Branch 3 taken 529581 times.
✓ Branch 4 taken 1605 times.
✓ Branch 5 taken 1337 times.
✓ Branch 6 taken 1605 times.
✓ Branch 7 taken 2017107 times.
2021677 if (tab->first_inner() != NO_PLAN_IDX && tab->first_inner() != tab->idx() &&
3434 2962 !join->best_ref[tab->first_inner()]->use_join_cache())
3435 1605 goto no_join_cache;
3436 /*
3437 The first inner table of an outer join nest must not use join buffering
3438 if the tables in the embedding outer join nest do not use join buffering.
3439 This condition is not handled by earlier optimizer stages.
3440 */
3441
6/6
✓ Branch 0 taken 809 times.
✓ Branch 1 taken 2016282 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 373 times.
✓ Branch 4 taken 382 times.
✓ Branch 5 taken 2016655 times.
2017862 if (tab->first_upper() != NO_PLAN_IDX &&
3442 809 !join->best_ref[tab->first_upper()]->use_join_cache())
3443 382 goto no_join_cache;
3444
3445
5/6
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 2016633 times.
✓ Branch 2 taken 77 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 77 times.
✓ Branch 5 taken 2016633 times.
2016655 if (tab->table()->pos_in_table_list->is_table_function() && tab->dependent)
3446 77 goto no_join_cache;
3447
3448
5/5
✓ Branch 0 taken 9224 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 8381 times.
✓ Branch 3 taken 1998861 times.
✓ Branch 4 taken 55 times.
2016633 switch (tab_sj_strategy) {
3449 9224 case SJ_OPT_FIRST_MATCH:
3450 /*
3451 Use join cache with FirstMatch semi-join strategy only when semi-join
3452 contains only one table.
3453 As mentioned earlier (in comments), we lift this restriction for
3454 secondary engine.
3455 */
3456
3/6
✓ Branch 0 taken 9224 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9224 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9224 times.
✗ Branch 5 not taken.
18448 if (!(current_thd->lex->m_sql_cmd != nullptr &&
3457
2/4
✓ Branch 0 taken 9224 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9224 times.
✗ Branch 3 not taken.
9224 current_thd->lex->m_sql_cmd->using_secondary_storage_engine())) {
3458
2/2
✓ Branch 0 taken 7245 times.
✓ Branch 1 taken 1979 times.
9224 if (!tab->is_single_inner_of_semi_join()) {
3459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7245 times.
7245 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3460 7245 goto no_join_cache;
3461 }
3462 }
3463 1979 break;
3464
3465 112 case SJ_OPT_LOOSE_SCAN:
3466 /* No join buffering if this semijoin nest is handled by loosescan */
3467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3468 112 goto no_join_cache;
3469
3470 8381 case SJ_OPT_MATERIALIZE_LOOKUP:
3471 case SJ_OPT_MATERIALIZE_SCAN:
3472 /*
3473 The Materialize strategies reuse the join_tab belonging to the
3474 first table that was materialized. Neither table can use join buffering:
3475 - The first table in a join never uses join buffering.
3476 - The join_tab used for looking up a row in the materialized table, or
3477 scanning the rows of a materialized table, cannot use join buffering.
3478 We allow join buffering for the remaining tables of the materialized
3479 semi-join nest.
3480 */
3481
2/2
✓ Branch 0 taken 4561 times.
✓ Branch 1 taken 3820 times.
8381 if (tab->first_sj_inner() == tab->idx()) {
3482
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4561 times.
4561 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3483 4561 goto no_join_cache;
3484 }
3485 3820 break;
3486
3487 1998861 case SJ_OPT_DUPS_WEEDOUT:
3488 // This strategy allows the same join buffering as a regular join would.
3489 case SJ_OPT_NONE:
3490 1998861 break;
3491 }
3492
3493 /*
3494 The following code prevents use of join buffering when there is an
3495 outer join operation and first match semi-join strategy is used, because:
3496
3497 Outer join needs a "match flag" to track that a row should be
3498 NULL-complemented, such flag being attached to first inner table's cache
3499 (tracks whether the cached row from outer table got a match, in which case
3500 no NULL-complemented row is needed).
3501
3502 FirstMatch also needs a "match flag", such flag is attached to sj inner
3503 table's cache (tracks whether the cached row from outer table already got
3504 a first match in the sj-inner table, in which case we don't need to join
3505 this cached row again)
3506 - but a row in a cache has only one "match flag"
3507 - so if "sj inner table"=="first inner", there is a problem.
3508
3509 As mentioned earlier(in comments), we lift this restriction for
3510 secondary engine.
3511 */
3512
5/6
✓ Branch 0 taken 2004698 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1989720 times.
✓ Branch 3 taken 14978 times.
✓ Branch 4 taken 2004633 times.
✓ Branch 5 taken 95 times.
3994465 if (!(current_thd->lex->m_sql_cmd != nullptr &&
3513
3/4
✓ Branch 0 taken 1989758 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1989651 times.
✓ Branch 3 taken 99 times.
1989720 current_thd->lex->m_sql_cmd->using_secondary_storage_engine())) {
3514
6/6
✓ Branch 0 taken 1979 times.
✓ Branch 1 taken 2002654 times.
✓ Branch 2 taken 118 times.
✓ Branch 3 taken 1861 times.
✓ Branch 4 taken 118 times.
✓ Branch 5 taken 2004515 times.
2006612 if (tab_sj_strategy == SJ_OPT_FIRST_MATCH &&
3515 1979 tab->is_inner_table_of_outer_join())
3516 118 goto no_join_cache;
3517 }
3518
3519 4009248 if (join->deps_of_remaining_lateral_derived_tables &
3520
2/2
✓ Branch 0 taken 593 times.
✓ Branch 1 taken 2004045 times.
2004610 (tab->prefix_tables() & ~tab->added_tables())) {
3521 /*
3522 Even though the planner said "no jbuf please", the switch below may
3523 force it.
3524 If first-dependency-of-lateral-table < table-we-plan-for <=
3525 lateral-table, disable join buffering.
3526 Reason for this rule:
3527 consider a plan t1-t2-dt where dt is LATERAL and depends only on t1, and
3528 imagine t2 could do join buffering: then we buffer many rows of t1, then
3529 read one row of t2, fetch row#1 of t1 from cache, then materialize "dt"
3530 (as it depends on t1) and send row to client; then fetch row#2 of t1
3531 from cache, rematerialize "dt": it's very inefficient. So we forbid join
3532 buffering on t2; this way, the signal "row of t1 changed" is emitted at
3533 the level of t1's operator, i.e. much less often, as one row of t1 may
3534 serve N rows of t2 before changing.
3535 On the other hand, t1 can do join buffering.
3536 A nice side-effect is to disable join buffering for "dt" itself. If
3537 "dt" would do join buffering: "dt" buffers many rows from t1/t2, then in a
3538 second phase we read one row from "dt" and join it with the many rows
3539 from t1/t2; but we cannot read a row from "dt" without first choosing a
3540 row of t1/t2 as "dt" depends on t1.
3541 See similar code in best_access_path().
3542 */
3543 593 goto no_join_cache;
3544 }
3545
3546
3/3
✓ Branch 0 taken 140083 times.
✓ Branch 1 taken 1863899 times.
✓ Branch 2 taken 73 times.
2004045 switch (tab->type()) {
3547 140083 case JT_ALL:
3548 case JT_INDEX_SCAN:
3549 case JT_RANGE:
3550 case JT_INDEX_MERGE:
3551
2/2
✓ Branch 0 taken 8840 times.
✓ Branch 1 taken 131243 times.
140083 if (!bnl_on) {
3552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8840 times.
8840 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3553 8840 goto no_join_cache;
3554 }
3555
3556
2/2
✓ Branch 0 taken 131156 times.
✓ Branch 1 taken 87 times.
131243 if (!join->select_count) tab->set_use_join_cache(JOIN_CACHE::ALG_BNL);
3557 131243 return false;
3558 1863899 case JT_SYSTEM:
3559 case JT_CONST:
3560 case JT_REF:
3561 case JT_EQ_REF:
3562
2/2
✓ Branch 0 taken 1858334 times.
✓ Branch 1 taken 5565 times.
1863899 if (!bka_on) {
3563
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1858304 times.
1858334 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3564 1858304 goto no_join_cache;
3565 }
3566
3567 /*
3568 Disable BKA for materializable derived tables/views as they aren't
3569 instantiated yet.
3570 */
3571
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 5500 times.
5565 if (tab->table_ref->uses_materialization()) goto no_join_cache;
3572
3573 /*
3574 Can't use BKA for subquery if dealing with a subquery that can
3575 turn a ref access into a "full scan on NULL key" table scan.
3576
3577 @see Item_in_optimizer::val_int()
3578 @see subselect_iterator_engine::exec()
3579 @see TABLE_REF::cond_guards
3580 @see push_index_cond()
3581
3582 @todo: This choice to not use BKA should be done before making
3583 cost estimates, e.g. in set_join_buffer_properties(). That
3584 happens before cond guards are set up, so instead of doing the
3585 check below, BKA should be disabled if
3586 - We are in an IN subquery, and
3587 - The IN predicate is not a top_level_item, and
3588 - The left_expr of the IN predicate may contain NULL values
3589 (left_expr->maybe_null)
3590 */
3591
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 5452 times.
5500 if (tab->has_guarded_conds()) goto no_join_cache;
3592
3593
2/2
✓ Branch 0 taken 1884 times.
✓ Branch 1 taken 3568 times.
5452 if (tab->table()->covering_keys.is_set(tab->ref().key))
3594 1884 join_cache_flags |= HA_MRR_INDEX_ONLY;
3595 5452 rows = tab->table()->file->multi_range_read_info(
3596
1/2
✓ Branch 0 taken 5452 times.
✗ Branch 1 not taken.
5452 tab->ref().key, 10, 20, &bufsz, &join_cache_flags, &cost);
3597 /*
3598 Cannot use BKA if
3599 1. MRR scan cannot be performed, or
3600 2. MRR default implementation is used, or
3601 3. HA_MRR_NO_ASSOCIATION flag is set
3602 */
3603
1/2
✓ Branch 0 taken 5452 times.
✗ Branch 1 not taken.
5452 if ((rows == HA_POS_ERROR) || // 1
3604
2/2
✓ Branch 0 taken 558 times.
✓ Branch 1 taken 4894 times.
5452 (join_cache_flags & HA_MRR_USE_DEFAULT_IMPL) || // 2
3605
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 558 times.
558 (join_cache_flags & HA_MRR_NO_ASSOCIATION)) // 3
3606 4894 goto no_join_cache;
3607
3608 558 tab->set_use_join_cache(JOIN_CACHE::ALG_BKA);
3609
3610 558 tab->join_cache_flags = join_cache_flags;
3611 558 return false;
3612 default:;
3613 }
3614
3615 1915735 no_join_cache:
3616
1/2
✓ Branch 0 taken 1915670 times.
✗ Branch 1 not taken.
1915735 revise_cache_usage(tab);
3617 1915670 tab->set_use_join_cache(JOIN_CACHE::ALG_NONE);
3618 1915710 return false;
3619 }
3620
3621 /*****************************************************************************
3622 Make some simple condition optimization:
3623 If there is a test 'field = const' change all refs to 'field' to 'const'
3624 Remove all dummy tests 'item = item', 'const op const'.
3625 Remove all 'item is NULL', when item can never be null!
3626 Return in cond_value false if condition is impossible (1 = 2)
3627 *****************************************************************************/
3628
3629 class COND_CMP : public ilink<COND_CMP> {
3630 public:
3631 52 static void *operator new(size_t size) { return (*THR_MALLOC)->Alloc(size); }
3632 static void operator delete(void *ptr [[maybe_unused]],
3633 size_t size [[maybe_unused]]) {
3634 TRASH(ptr, size);
3635 }
3636
3637 Item *and_level;
3638 Item_func *cmp_func;
3639 52 COND_CMP(Item *a, Item_func *b) : and_level(a), cmp_func(b) {}
3640 };
3641
3642 9067711 Item_equal *find_item_equal(COND_EQUAL *cond_equal,
3643 const Item_field *item_field, bool *inherited_fl) {
3644 9067711 Item_equal *item = nullptr;
3645 9067711 bool in_upper_level = false;
3646
2/2
✓ Branch 0 taken 10405208 times.
✓ Branch 1 taken 7554870 times.
17960078 while (cond_equal) {
3647
1/2
✓ Branch 0 taken 10405471 times.
✗ Branch 1 not taken.
10405208 List_iterator_fast<Item_equal> li(cond_equal->current_level);
3648
2/2
✓ Branch 0 taken 21388858 times.
✓ Branch 1 taken 8892367 times.
30281442 while ((item = li++)) {
3649
3/4
✓ Branch 0 taken 21389166 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1513195 times.
✓ Branch 3 taken 19875971 times.
21388858 if (item->contains(item_field->field)) goto finish;
3650 }
3651 8892367 in_upper_level = true;
3652 8892367 cond_equal = cond_equal->upper_levels;
3653 }
3654 7554870 in_upper_level = false;
3655 9068065 finish:
3656 9068065 *inherited_fl = in_upper_level;
3657 9068065 return item;
3658 }
3659
3660 /**
3661 Get the best field substitution for a given field.
3662
3663 If the field is member of a multiple equality, look up that equality
3664 and return the most appropriate field. Usually this is the equivalenced
3665 field belonging to the outer-most table in the join order, but
3666 @see Item_field::get_subst_item() for details.
3667 Otherwise, return the same field.
3668
3669 @param item_field The field that we are seeking a substitution for.
3670 @param cond_equal multiple equalities to search in
3671
3672 @return The substituted field.
3673 */
3674
3675 1846835 Item_field *get_best_field(Item_field *item_field, COND_EQUAL *cond_equal) {
3676 bool dummy;
3677
1/2
✓ Branch 0 taken 1846951 times.
✗ Branch 1 not taken.
1846835 Item_equal *item_eq = find_item_equal(cond_equal, item_field, &dummy);
3678
2/2
✓ Branch 0 taken 524224 times.
✓ Branch 1 taken 1322727 times.
1846951 if (!item_eq) return item_field;
3679
3680
1/2
✓ Branch 0 taken 1322730 times.
✗ Branch 1 not taken.
1322727 return item_eq->get_subst_item(item_field);
3681 }
3682
3683 /**
3684 Check whether an equality can be used to build multiple equalities.
3685
3686 This function first checks whether the equality (left_item=right_item)
3687 is a simple equality i.e. one that equates a field with another field
3688 or a constant (field=field_item or field=const_item).
3689 If this is the case the function looks for a multiple equality
3690 in the lists referenced directly or indirectly by cond_equal inferring
3691 the given simple equality. If it doesn't find any, it builds a multiple
3692 equality that covers the predicate, i.e. the predicate can be inferred
3693 from this multiple equality.
3694 The built multiple equality could be obtained in such a way:
3695 create a binary multiple equality equivalent to the predicate, then
3696 merge it, if possible, with one of old multiple equalities.
3697 This guarantees that the set of multiple equalities covering equality
3698 predicates will be minimal.
3699
3700 EXAMPLE:
3701 For the where condition
3702 @code
3703 WHERE a=b AND b=c AND
3704 (b=2 OR f=e)
3705 @endcode
3706 the check_equality will be called for the following equality
3707 predicates a=b, b=c, b=2 and f=e.
3708 - For a=b it will be called with *cond_equal=(0,[]) and will transform
3709 *cond_equal into (0,[Item_equal(a,b)]).
3710 - For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)])
3711 and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]).
3712 - For b=2 it will be called with *cond_equal=(ptr(CE),[])
3713 and will transform *cond_equal into (ptr(CE),[Item_equal(2,a,b,c)]).
3714 - For f=e it will be called with *cond_equal=(ptr(CE), [])
3715 and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]).
3716
3717 @note
3718 Now only fields that have the same type definitions (verified by
3719 the Field::eq_def method) are placed to the same multiple equalities.
3720 Because of this some equality predicates are not eliminated and
3721 can be used in the constant propagation procedure.
3722 We could weaken the equality test as soon as at least one of the
3723 equal fields is to be equal to a constant. It would require a
3724 more complicated implementation: we would have to store, in
3725 general case, its own constant for each fields from the multiple
3726 equality. But at the same time it would allow us to get rid
3727 of constant propagation completely: it would be done by the call
3728 to build_equal_items_for_cond.
3729
3730 The implementation does not follow exactly the above rules to
3731 build a new multiple equality for the equality predicate.
3732 If it processes the equality of the form field1=field2, it
3733 looks for multiple equalities me1 containing field1 and me2 containing
3734 field2. If only one of them is found the function expands it with
3735 the lacking field. If multiple equalities for both fields are
3736 found they are merged. If both searches fail a new multiple equality
3737 containing just field1 and field2 is added to the existing
3738 multiple equalities.
3739 If the function processes the predicate of the form field1=const,
3740 it looks for a multiple equality containing field1. If found, the
3741 function checks the constant of the multiple equality. If the value
3742 is unknown, it is setup to const. Otherwise the value is compared with
3743 const and the evaluation of the equality predicate is performed.
3744 When expanding/merging equality predicates from the upper levels
3745 the function first copies them for the current level. It looks
3746 acceptable, as this happens rarely. The implementation without
3747 copying would be much more complicated.
3748
3749 @param thd Thread handler
3750 @param left_item left term of the equality to be checked
3751 @param right_item right term of the equality to be checked
3752 @param item equality item if the equality originates from a condition
3753 predicate, 0 if the equality is the result of row
3754 elimination
3755 @param cond_equal multiple equalities that must hold together with the
3756 equality
3757 @param[out] simple_equality
3758 true if the predicate is a simple equality predicate
3759 to be used for building multiple equalities
3760 false otherwise
3761
3762 @returns false if success, true if error
3763 */
3764
3765 5466686 static bool check_simple_equality(THD *thd, Item *left_item, Item *right_item,
3766 Item *item, COND_EQUAL *cond_equal,
3767 bool *simple_equality) {
3768 5466686 *simple_equality = false;
3769
3770
4/4
✓ Branch 0 taken 307568 times.
✓ Branch 1 taken 5159241 times.
✓ Branch 2 taken 304622 times.
✓ Branch 3 taken 5162155 times.
5774222 if (left_item->type() == Item::REF_ITEM &&
3771
2/2
✓ Branch 0 taken 304597 times.
✓ Branch 1 taken 2939 times.
307568 down_cast<Item_ref *>(left_item)->ref_type() == Item_ref::VIEW_REF) {
3772
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 304609 times.
304622 if (down_cast<Item_ref *>(left_item)->is_outer_reference()) return false;
3773 304609 left_item = left_item->real_item();
3774 }
3775
4/4
✓ Branch 0 taken 10460 times.
✓ Branch 1 taken 5456273 times.
✓ Branch 2 taken 9132 times.
✓ Branch 3 taken 5457615 times.
5477270 if (right_item->type() == Item::REF_ITEM &&
3776
2/2
✓ Branch 0 taken 9132 times.
✓ Branch 1 taken 1342 times.
10460 down_cast<Item_ref *>(right_item)->ref_type() == Item_ref::VIEW_REF) {
3777
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 9108 times.
9132 if (down_cast<Item_ref *>(right_item)->is_outer_reference()) return false;
3778 9108 right_item = right_item->real_item();
3779 }
3780 const Item_field *left_item_field, *right_item_field;
3781
3782 5466723 if (left_item->type() == Item::FIELD_ITEM &&
3783
3/4
✓ Branch 0 taken 2202457 times.
✓ Branch 1 taken 3188920 times.
✓ Branch 2 taken 2202466 times.
✗ Branch 3 not taken.
7593789 right_item->type() == Item::FIELD_ITEM &&
3784
1/2
✓ Branch 0 taken 2202477 times.
✗ Branch 1 not taken.
4404930 (left_item_field = down_cast<const Item_field *>(left_item)) &&
3785 2202466 (right_item_field = down_cast<const Item_field *>(right_item)) &&
3786
8/8
✓ Branch 0 taken 5391325 times.
✓ Branch 1 taken 75370 times.
✓ Branch 2 taken 2201220 times.
✓ Branch 3 taken 1257 times.
✓ Branch 4 taken 2196894 times.
✓ Branch 5 taken 4326 times.
✓ Branch 6 taken 2196895 times.
✓ Branch 7 taken 3269866 times.
10858086 !left_item_field->depended_from && !right_item_field->depended_from) {
3787 /* The predicate the form field1=field2 is processed */
3788
3789 2196895 const Field *const left_field = left_item_field->field;
3790 2196895 const Field *const right_field = right_item_field->field;
3791
3792
3/4
✓ Branch 0 taken 2196893 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43937 times.
✓ Branch 3 taken 2152956 times.
2196895 if (!left_field->eq_def(right_field)) return false;
3793
3794 /* Search for multiple equalities containing field1 and/or field2 */
3795 bool left_copyfl, right_copyfl;
3796 Item_equal *left_item_equal =
3797
1/2
✓ Branch 0 taken 2152935 times.
✗ Branch 1 not taken.
2152956 find_item_equal(cond_equal, left_item_field, &left_copyfl);
3798 Item_equal *right_item_equal =
3799
1/2
✓ Branch 0 taken 2152943 times.
✗ Branch 1 not taken.
2152935 find_item_equal(cond_equal, right_item_field, &right_copyfl);
3800
3801 /* As (NULL=NULL) != TRUE we can't just remove the predicate f=f */
3802
3/4
✓ Branch 0 taken 2152910 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 2152656 times.
2152943 if (left_field->eq(right_field)) /* f = f */
3803 {
3804 254 *simple_equality =
3805
6/6
✓ Branch 0 taken 193 times.
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 185 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 68 times.
254 !((left_field->is_nullable() || left_field->table->is_nullable()) &&
3806 !left_item_equal);
3807 254 return false;
3808 }
3809
3810
4/4
✓ Branch 0 taken 160853 times.
✓ Branch 1 taken 1991803 times.
✓ Branch 2 taken 157 times.
✓ Branch 3 taken 160696 times.
2152656 if (left_item_equal && left_item_equal == right_item_equal) {
3811 /*
3812 The equality predicate is inference of one of the existing
3813 multiple equalities, i.e the condition is already covered
3814 by upper level equalities
3815 */
3816 157 *simple_equality = true;
3817 157 return false;
3818 }
3819
3820 /* Copy the found multiple equalities at the current level if needed */
3821
2/2
✓ Branch 0 taken 156983 times.
✓ Branch 1 taken 1995516 times.
2152499 if (left_copyfl) {
3822 /* left_item_equal of an upper level contains left_item */
3823
2/4
✓ Branch 0 taken 156974 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 156986 times.
✗ Branch 3 not taken.
156983 left_item_equal = new Item_equal(left_item_equal);
3824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156986 times.
156986 if (left_item_equal == nullptr) return true;
3825
1/2
✓ Branch 0 taken 156978 times.
✗ Branch 1 not taken.
156986 cond_equal->current_level.push_back(left_item_equal);
3826 }
3827
2/2
✓ Branch 0 taken 413 times.
✓ Branch 1 taken 2152081 times.
2152494 if (right_copyfl) {
3828 /* right_item_equal of an upper level contains right_item */
3829
2/4
✓ Branch 0 taken 413 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 413 times.
✗ Branch 3 not taken.
413 right_item_equal = new Item_equal(right_item_equal);
3830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 413 times.
413 if (right_item_equal == nullptr) return true;
3831
1/2
✓ Branch 0 taken 378 times.
✗ Branch 1 not taken.
413 cond_equal->current_level.push_back(right_item_equal);
3832 }
3833
3834
2/2
✓ Branch 0 taken 160682 times.
✓ Branch 1 taken 1991777 times.
2152459 if (left_item_equal) {
3835 /* left item was found in the current or one of the upper levels */
3836
2/2
✓ Branch 0 taken 160505 times.
✓ Branch 1 taken 177 times.
160682 if (!right_item_equal)
3837
1/2
✓ Branch 0 taken 160508 times.
✗ Branch 1 not taken.
160505 left_item_equal->add(down_cast<Item_field *>(right_item));
3838 else {
3839 /* Merge two multiple equalities forming a new one */
3840
2/4
✓ Branch 0 taken 177 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 177 times.
177 if (left_item_equal->merge(thd, right_item_equal)) return true;
3841 /* Remove the merged multiple equality from the list */
3842
1/2
✓ Branch 0 taken 177 times.
✗ Branch 1 not taken.
177 List_iterator<Item_equal> li(cond_equal->current_level);
3843
2/2
✓ Branch 0 taken 154 times.
✓ Branch 1 taken 177 times.
331 while ((li++) != right_item_equal)
3844 ;
3845
1/2
✓ Branch 0 taken 177 times.
✗ Branch 1 not taken.
177 li.remove();
3846 }
3847 } else {
3848 /* left item was not found neither the current nor in upper levels */
3849
2/2
✓ Branch 0 taken 28374 times.
✓ Branch 1 taken 1963403 times.
1991777 if (right_item_equal) {
3850
1/2
✓ Branch 0 taken 28376 times.
✗ Branch 1 not taken.
28374 right_item_equal->add(down_cast<Item_field *>(left_item));
3851 } else {
3852 /* None of the fields was found in multiple equalities */
3853 Item_equal *item_equal =
3854 1963403 new Item_equal(down_cast<Item_field *>(left_item),
3855
2/4
✓ Branch 0 taken 1963439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1963457 times.
✗ Branch 3 not taken.
1963430 down_cast<Item_field *>(right_item));
3856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1963457 times.
1963457 if (item_equal == nullptr) return true;
3857
1/2
✓ Branch 0 taken 1963453 times.
✗ Branch 1 not taken.
1963457 cond_equal->current_level.push_back(item_equal);
3858 }
3859 }
3860 2152514 *simple_equality = true;
3861 2152514 return false;
3862 }
3863
3864 {
3865 /* The predicate of the form field=const/const=field is processed */
3866 3269866 Item *const_item = nullptr;
3867 3269866 Item_field *field_item = nullptr;
3868
1/2
✓ Branch 0 taken 3194462 times.
✗ Branch 1 not taken.
6464315 if (left_item->type() == Item::FIELD_ITEM &&
3869 3194382 (field_item = down_cast<Item_field *>(left_item)) &&
3870
6/6
✓ Branch 0 taken 3194382 times.
✓ Branch 1 taken 75423 times.
✓ Branch 2 taken 3192993 times.
✓ Branch 3 taken 1469 times.
✓ Branch 4 taken 3175584 times.
✓ Branch 5 taken 94250 times.
9657209 field_item->depended_from == nullptr &&
3871
2/2
✓ Branch 0 taken 3175569 times.
✓ Branch 1 taken 17386 times.
3192993 right_item->const_for_execution()) {
3872 3175584 const_item = right_item;
3873
1/2
✓ Branch 0 taken 26388 times.
✗ Branch 1 not taken.
120638 } else if (right_item->type() == Item::FIELD_ITEM &&
3874 26388 (field_item = down_cast<Item_field *>(right_item)) &&
3875
6/6
✓ Branch 0 taken 26388 times.
✓ Branch 1 taken 67877 times.
✓ Branch 2 taken 21820 times.
✓ Branch 3 taken 4568 times.
✓ Branch 4 taken 18635 times.
✓ Branch 5 taken 75630 times.
142473 field_item->depended_from == nullptr &&
3876
2/2
✓ Branch 0 taken 18635 times.
✓ Branch 1 taken 3185 times.
21820 left_item->const_for_execution()) {
3877 18635 const_item = left_item;
3878 }
3879
3880 // Don't evaluate subqueries if they are disabled during optimization.
3881
3/4
✓ Branch 0 taken 3194197 times.
✓ Branch 1 taken 75652 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3269899 times.
6464096 if (const_item != nullptr &&
3882
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3194247 times.
3194265 !evaluate_during_optimization(const_item,
3883 3194197 thd->lex->current_query_block()))
3884 return false;
3885
3886 /*
3887 If the constant expression contains a reference to the field
3888 (for example, a = (a IS NULL)), we don't want to replace the
3889 field with the constant expression as it makes the predicates
3890 more complex and may introduce cycles in the Item tree.
3891 */
3892
3/4
✓ Branch 0 taken 3194266 times.
✓ Branch 1 taken 75633 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3269804 times.
6464070 if (const_item != nullptr &&
3893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3194171 times.
3194255 const_item->walk(&Item::find_field_processor, enum_walk::POSTFIX,
3894 3194266 pointer_cast<uchar *>(field_item->field)))
3895 return false;
3896
3897
6/6
✓ Branch 0 taken 3194191 times.
✓ Branch 1 taken 75613 times.
✓ Branch 2 taken 3184092 times.
✓ Branch 3 taken 10148 times.
✓ Branch 4 taken 3184077 times.
✓ Branch 5 taken 85776 times.
3269804 if (const_item && field_item->result_type() == const_item->result_type()) {
3898
3/4
✓ Branch 0 taken 3184158 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 944175 times.
✓ Branch 3 taken 2239983 times.
3184077 if (field_item->result_type() == STRING_RESULT) {
3899
1/2
✓ Branch 0 taken 944183 times.
✗ Branch 1 not taken.
944175 const CHARSET_INFO *cs = field_item->field->charset();
3900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 944183 times.
944183 if (!item) {
3901 Item_func_eq *const eq_item = new Item_func_eq(left_item, right_item);
3902 if (eq_item == nullptr || eq_item->set_cmp_func()) return true;
3903 eq_item->quick_fix_field();
3904 item = eq_item;
3905 }
3906
5/6
✓ Branch 0 taken 944161 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 940684 times.
✓ Branch 3 taken 3477 times.
✓ Branch 4 taken 269561 times.
✓ Branch 5 taken 674571 times.
1884838 if ((cs != down_cast<Item_func *>(item)->compare_collation()) ||
3907
3/4
✓ Branch 0 taken 940655 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 266084 times.
✓ Branch 3 taken 674571 times.
940684 !cs->coll->propagate(cs, nullptr, 0))
3908 269561 return false;
3909 }
3910
3911 bool copyfl;
3912
1/2
✓ Branch 0 taken 2914564 times.
✗ Branch 1 not taken.
2914554 Item_equal *item_equal = find_item_equal(cond_equal, field_item, &copyfl);
3913
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 2914347 times.
2914564 if (copyfl) {
3914
2/4
✓ Branch 0 taken 217 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 217 times.
✗ Branch 3 not taken.
217 item_equal = new Item_equal(item_equal);
3915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 217 times.
217 if (item_equal == nullptr) return true;
3916
1/2
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
217 cond_equal->current_level.push_back(item_equal);
3917 }
3918
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 2913764 times.
2914536 if (item_equal) {
3919 /*
3920 The flag cond_false will be set to 1 after this, if item_equal
3921 already contains a constant and its value is not equal to
3922 the value of const_item.
3923 */
3924
3/4
✓ Branch 0 taken 772 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 771 times.
772 if (item_equal->add(thd, const_item, field_item)) return true;
3925 } else {
3926
2/4
✓ Branch 0 taken 2913808 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2913767 times.
✗ Branch 3 not taken.
2913764 item_equal = new Item_equal(const_item, field_item);
3927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2913767 times.
2913767 if (item_equal == nullptr) return true;
3928
1/2
✓ Branch 0 taken 2913845 times.
✗ Branch 1 not taken.
2913767 cond_equal->current_level.push_back(item_equal);
3929 }
3930 2914616 *simple_equality = true;
3931 2914616 return false;
3932 }
3933 }
3934 85776 return false;
3935 }
3936
3937 /**
3938 Convert row equalities into a conjunction of regular equalities.
3939
3940 The function converts a row equality of the form (E1,...,En)=(E'1,...,E'n)
3941 into a list of equalities E1=E'1,...,En=E'n. For each of these equalities
3942 Ei=E'i the function checks whether it is a simple equality or a row
3943 equality. If it is a simple equality it is used to expand multiple
3944 equalities of cond_equal. If it is a row equality it converted to a
3945 sequence of equalities between row elements. If Ei=E'i is neither a
3946 simple equality nor a row equality the item for this predicate is added
3947 to eq_list.
3948
3949 @param thd thread handle
3950 @param left_row left term of the row equality to be processed
3951 @param right_row right term of the row equality to be processed
3952 @param cond_equal multiple equalities that must hold together with the
3953 predicate
3954 @param eq_list results of conversions of row equalities that are not
3955 simple enough to form multiple equalities
3956 @param[out] simple_equality
3957 true if the row equality is composed of only
3958 simple equalities.
3959
3960 @returns false if conversion succeeded, true if any error.
3961 */
3962
3963 68 static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
3964 COND_EQUAL *cond_equal, List<Item> *eq_list,
3965 bool *simple_equality) {
3966 68 *simple_equality = false;
3967 68 uint n = left_row->cols();
3968
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 68 times.
220 for (uint i = 0; i < n; i++) {
3969 bool is_converted;
3970
1/2
✓ Branch 0 taken 152 times.
✗ Branch 1 not taken.
152 Item *left_item = left_row->element_index(i);
3971
1/2
✓ Branch 0 taken 152 times.
✗ Branch 1 not taken.
152 Item *right_item = right_row->element_index(i);
3972
3/6
✓ Branch 0 taken 152 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 152 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 152 times.
152 if (left_item->type() == Item::ROW_ITEM &&
3973 right_item->type() == Item::ROW_ITEM) {
3974 if (check_row_equality(thd, down_cast<Item_row *>(left_item),
3975 down_cast<Item_row *>(right_item), cond_equal,
3976 eq_list, &is_converted))
3977 return true;
3978 if (!is_converted) thd->lex->current_query_block()->cond_count++;
3979 } else {
3980
2/4
✓ Branch 0 taken 152 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 152 times.
152 if (check_simple_equality(thd, left_item, right_item, nullptr, cond_equal,
3981 &is_converted))
3982 return true;
3983 152 thd->lex->current_query_block()->cond_count++;
3984 }
3985
3986
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 140 times.
152 if (!is_converted) {
3987
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 Item_func_eq *const eq_item = new Item_func_eq(left_item, right_item);
3988
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (eq_item == nullptr) return true;
3989
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if (eq_item->set_cmp_func()) {
3990 // Failed to create cmp func -> not only simple equalitities
3991 return true;
3992 }
3993 12 eq_item->quick_fix_field();
3994
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 eq_list->push_back(eq_item);
3995 }
3996 }
3997 68 *simple_equality = true;
3998 68 return false;
3999 }
4000
4001 /**
4002 Eliminate row equalities and form multiple equalities predicates.
4003
4004 This function checks whether the item is a simple equality
4005 i.e. the one that equates a field with another field or a constant
4006 (field=field_item or field=constant_item), or, a row equality.
4007 For a simple equality the function looks for a multiple equality
4008 in the lists referenced directly or indirectly by cond_equal inferring
4009 the given simple equality. If it doesn't find any, it builds/expands
4010 multiple equality that covers the predicate.
4011 Row equalities are eliminated substituted for conjunctive regular
4012 equalities which are treated in the same way as original equality
4013 predicates.
4014
4015 @param thd thread handle
4016 @param item predicate to process
4017 @param cond_equal multiple equalities that must hold together with the
4018 predicate
4019 @param eq_list results of conversions of row equalities that are not
4020 simple enough to form multiple equalities
4021 @param[out] equality
4022 true if re-writing rules have been applied
4023 false otherwise, i.e.
4024 if the predicate is not an equality, or
4025 if the equality is neither a simple nor a row equality
4026
4027 @returns false if success, true if error
4028
4029 @note If the equality was created by IN->EXISTS, it may be removed later by
4030 subquery materialization. So we don't mix this possibly temporary equality
4031 with others; if we let it go into a multiple-equality (Item_equal), then we
4032 could not remove it later. There is however an exception: if the outer
4033 expression is a constant, it is safe to leave the equality even in
4034 materialization; all it can do is preventing NULL/FALSE distinction but if
4035 such distinction mattered the equality would be in a triggered condition so
4036 we would not come to this function. And injecting constants is good because
4037 it makes the materialized table smaller.
4038 */
4039
4040 8409975 static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
4041 List<Item> *eq_list, bool *equality) {
4042 8409975 *equality = false;
4043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8410094 times.
8409975 assert(item->is_bool_func());
4044 Item_func *item_func;
4045
4/4
✓ Branch 0 taken 8402339 times.
✓ Branch 1 taken 7742 times.
✓ Branch 2 taken 5477738 times.
✓ Branch 3 taken 2932205 times.
16812295 if (item->type() == Item::FUNC_ITEM &&
4046
2/2
✓ Branch 0 taken 5477675 times.
✓ Branch 1 taken 2924526 times.
8402339 (item_func = down_cast<Item_func *>(item))->functype() ==
4047 Item_func::EQ_FUNC) {
4048 5477738 Item *left_item = item_func->arguments()[0];
4049 5477717 Item *right_item = item_func->arguments()[1];
4050
4051
6/6
✓ Branch 0 taken 13609 times.
✓ Branch 1 taken 5464072 times.
✓ Branch 2 taken 11013 times.
✓ Branch 3 taken 2596 times.
✓ Branch 4 taken 11013 times.
✓ Branch 5 taken 5466668 times.
5477744 if (item->created_by_in2exists() && !left_item->const_item())
4052 11013 return false; // See note above
4053
4054
4/4
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 5466525 times.
✓ Branch 2 taken 68 times.
✓ Branch 3 taken 5466564 times.
5466775 if (left_item->type() == Item::ROW_ITEM &&
4055
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 39 times.
101 right_item->type() == Item::ROW_ITEM) {
4056 68 thd->lex->current_query_block()->cond_count--;
4057 68 return check_row_equality(thd, down_cast<Item_row *>(left_item),
4058 down_cast<Item_row *>(right_item), cond_equal,
4059 68 eq_list, equality);
4060 } else
4061 5466564 return check_simple_equality(thd, left_item, right_item, item, cond_equal,
4062 5466632 equality);
4063 }
4064
4065 2932205 return false;
4066 }
4067
4068 /**
4069 Replace all equality predicates in a condition by multiple equality items.
4070
4071 At each 'and' level the function detects items for equality predicates
4072 and replaces them by a set of multiple equality items of class Item_equal,
4073 taking into account inherited equalities from upper levels.
4074 If an equality predicate is used not in a conjunction it's just
4075 replaced by a multiple equality predicate.
4076 For each 'and' level the function set a pointer to the inherited
4077 multiple equalities in the cond_equal field of the associated
4078 object of the type Item_cond_and.
4079 The function also traverses the cond tree and for each field reference
4080 sets a pointer to the multiple equality item containing the field, if there
4081 is any. If this multiple equality equates fields to a constant the
4082 function replaces the field reference by the constant in the cases
4083 when the field is not of a string type or when the field reference is
4084 just an argument of a comparison predicate.
4085 The function also determines the maximum number of members in
4086 equality lists of each Item_cond_and object assigning it to
4087 thd->lex->current_query_block()->max_equal_elems.
4088
4089 @note
4090 Multiple equality predicate =(f1,..fn) is equivalent to the conjunction of
4091 f1=f2, .., fn-1=fn. It substitutes any inference from these
4092 equality predicates that is equivalent to the conjunction.
4093 Thus, =(a1,a2,a3) can substitute for ((a1=a3) AND (a2=a3) AND (a2=a1)) as
4094 it is equivalent to ((a1=a2) AND (a2=a3)).
4095 The function always makes a substitution of all equality predicates occurred
4096 in a conjunction for a minimal set of multiple equality predicates.
4097 This set can be considered as a canonical representation of the
4098 sub-conjunction of the equality predicates.
4099 E.g. (t1.a=t2.b AND t2.b>5 AND t1.a=t3.c) is replaced by
4100 (=(t1.a,t2.b,t3.c) AND t2.b>5), not by
4101 (=(t1.a,t2.b) AND =(t1.a,t3.c) AND t2.b>5);
4102 while (t1.a=t2.b AND t2.b>5 AND t3.c=t4.d) is replaced by
4103 (=(t1.a,t2.b) AND =(t3.c=t4.d) AND t2.b>5),
4104 but if additionally =(t4.d,t2.b) is inherited, it
4105 will be replaced by (=(t1.a,t2.b,t3.c,t4.d) AND t2.b>5)
4106
4107 The function performs the substitution in a recursive descent of
4108 the condition tree, passing to the next AND level a chain of multiple
4109 equality predicates which have been built at the upper levels.
4110 The Item_equal items built at the level are attached to other
4111 non-equality conjuncts as a sublist. The pointer to the inherited
4112 multiple equalities is saved in the and condition object (Item_cond_and).
4113 This chain allows us for any field reference occurrence to easily find a
4114 multiple equality that must be held for this occurrence.
4115 For each AND level we do the following:
4116 - scan it for all equality predicate (=) items
4117 - join them into disjoint Item_equal() groups
4118 - process the included OR conditions recursively to do the same for
4119 lower AND levels.
4120
4121 We need to do things in this order as lower AND levels need to know about
4122 all possible Item_equal objects in upper levels.
4123
4124 @param thd thread handle
4125 @param cond condition(expression) where to make replacement
4126 @param[out] retcond returned condition
4127 @param inherited path to all inherited multiple equality items
4128 @param do_inherit whether or not to inherit equalities from other parts
4129 of the condition
4130
4131 @returns false if success, true if error
4132 */
4133
4134 4536930 static bool build_equal_items_for_cond(THD *thd, Item *cond, Item **retcond,
4135 COND_EQUAL *inherited, bool do_inherit) {
4136 Item_equal *item_equal;
4137
1/2
✓ Branch 0 taken 4536953 times.
✗ Branch 1 not taken.
4536930 COND_EQUAL cond_equal;
4138 4536953 cond_equal.upper_levels = inherited;
4139
2/4
✓ Branch 0 taken 4536913 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4536913 times.
4536953 assert(cond->is_bool_func());
4140
2/4
✓ Branch 0 taken 4537098 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4537098 times.
4536913 if (check_stack_overrun(thd, STACK_MIN_SIZE, nullptr))
4141 return true; // Fatal error flag is set!
4142
4143
1/2
✓ Branch 0 taken 4536993 times.
✗ Branch 1 not taken.
4537098 const enum Item::Type cond_type = cond->type();
4144
2/2
✓ Branch 0 taken 1848692 times.
✓ Branch 1 taken 2688301 times.
4536993 if (cond_type == Item::COND_ITEM) {
4145 1848692 List<Item> eq_list;
4146 1848692 Item_cond *const item_cond = down_cast<Item_cond *>(cond);
4147
1/2
✓ Branch 0 taken 1848691 times.
✗ Branch 1 not taken.
1848677 const bool and_level = item_cond->functype() == Item_func::COND_AND_FUNC;
4148 1848691 List<Item> *args = item_cond->argument_list();
4149
4150
1/2
✓ Branch 0 taken 1848688 times.
✗ Branch 1 not taken.
1848683 List_iterator<Item> li(*args);
4151 Item *item;
4152
4153
2/2
✓ Branch 0 taken 1818312 times.
✓ Branch 1 taken 30376 times.
1848688 if (and_level) {
4154 /*
4155 Retrieve all conjuncts of this level detecting the equality
4156 that are subject to substitution by multiple equality items and
4157 removing each such predicate from the conjunction after having
4158 found/created a multiple equality whose inference the predicate is.
4159 */
4160
2/2
✓ Branch 0 taken 5722452 times.
✓ Branch 1 taken 1818288 times.
7540728 while ((item = li++)) {
4161 /*
4162 PS/SP note: we can safely remove a node from AND-OR
4163 structure here because it's restored before each
4164 re-execution of any prepared statement/stored procedure.
4165 */
4166 bool equality;
4167
3/4
✓ Branch 0 taken 5722386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 5722385 times.
5722452 if (check_equality(thd, item, &cond_equal, &eq_list, &equality))
4168 1 return true;
4169
3/4
✓ Branch 0 taken 4244189 times.
✓ Branch 1 taken 1478196 times.
✓ Branch 2 taken 4244220 times.
✗ Branch 3 not taken.
5722385 if (equality) li.remove();
4170 }
4171
4172 /*
4173 Check if we eliminated all the predicates of the level, e.g.
4174 (a=a AND b=b AND a=a).
4175 */
4176
4/4
✓ Branch 0 taken 1182440 times.
✓ Branch 1 taken 635848 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 1182395 times.
1818288 if (!args->elements && !cond_equal.current_level.elements &&
4177
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 !eq_list.elements) {
4178
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
90 *retcond = new Item_func_true();
4179 45 return *retcond == nullptr;
4180 }
4181
4182
1/2
✓ Branch 0 taken 1818268 times.
✗ Branch 1 not taken.
1818243 List_iterator_fast<Item_equal> it(cond_equal.current_level);
4183
2/2
✓ Branch 0 taken 4211442 times.
✓ Branch 1 taken 1818255 times.
6029720 while ((item_equal = it++)) {
4184
2/4
✓ Branch 0 taken 4211422 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4211422 times.
4211442 if (item_equal->resolve_type(thd)) return true;
4185
1/2
✓ Branch 0 taken 4211493 times.
✗ Branch 1 not taken.
4211422 item_equal->update_used_tables();
4186 8422900 thd->lex->current_query_block()->max_equal_elems =
4187 4211482 std::max(thd->lex->current_query_block()->max_equal_elems,
4188
1/2
✓ Branch 0 taken 4211497 times.
✗ Branch 1 not taken.
8422945 item_equal->members());
4189 }
4190
4191 1818255 Item_cond_and *const item_cond_and = down_cast<Item_cond_and *>(cond);
4192
1/2
✓ Branch 0 taken 1818250 times.
✗ Branch 1 not taken.
1818258 item_cond_and->cond_equal = cond_equal;
4193 1818250 inherited = &item_cond_and->cond_equal;
4194 }
4195 /*
4196 Make replacement of equality predicates for lower levels
4197 of the condition expression.
4198 */
4199 1848626 li.rewind();
4200
2/2
✓ Branch 0 taken 2505402 times.
✓ Branch 1 taken 1848645 times.
4354021 while ((item = li++)) {
4201 Item *new_item;
4202
2/4
✓ Branch 0 taken 2505379 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2505379 times.
2505402 if (build_equal_items_for_cond(thd, item, &new_item, inherited,
4203 do_inherit))
4204 return true;
4205
2/2
✓ Branch 0 taken 13085 times.
✓ Branch 1 taken 2492294 times.
2505379 if (new_item != item) {
4206 /* This replacement happens only for standalone equalities */
4207 /*
4208 This is ok with PS/SP as the replacement is done for
4209 arguments of an AND/OR item, which are restored for each
4210 execution of PS/SP.
4211 */
4212 13085 li.replace(new_item);
4213 }
4214 }
4215
2/2
✓ Branch 0 taken 1818265 times.
✓ Branch 1 taken 30380 times.
1848645 if (and_level) {
4216
1/2
✓ Branch 0 taken 1818243 times.
✗ Branch 1 not taken.
1818265 args->concat(&eq_list);
4217
1/2
✓ Branch 0 taken 1818268 times.
✗ Branch 1 not taken.
1818243 args->concat((List<Item> *)&cond_equal.current_level);
4218 }
4219
3/4
✓ Branch 0 taken 2688280 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2687612 times.
✓ Branch 3 taken 668 times.
2688301 } else if (cond->type() == Item::FUNC_ITEM) {
4220 2687612 List<Item> eq_list;
4221 /*
4222 If an equality predicate forms the whole and level,
4223 we call it standalone equality and it's processed here.
4224 E.g. in the following where condition
4225 WHERE a=5 AND (b=5 or a=c)
4226 (b=5) and (a=c) are standalone equalities.
4227 In general we can't leave alone standalone eqalities:
4228 for WHERE a=b AND c=d AND (b=c OR d=5)
4229 b=c is replaced by =(a,b,c,d).
4230 */
4231 bool equality;
4232
2/4
✓ Branch 0 taken 2687619 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2687619 times.
2687612 if (check_equality(thd, cond, &cond_equal, &eq_list, &equality))
4233 823117 return true;
4234
2/2
✓ Branch 0 taken 823183 times.
✓ Branch 1 taken 1864436 times.
2687619 if (equality) {
4235 823183 int n = cond_equal.current_level.elements + eq_list.elements;
4236
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 823158 times.
823183 if (n == 0) {
4237
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
50 *retcond = new Item_func_true();
4238 25 return *retcond == nullptr;
4239
2/2
✓ Branch 0 taken 823094 times.
✓ Branch 1 taken 64 times.
823158 } else if (n == 1) {
4240
2/2
✓ Branch 0 taken 823040 times.
✓ Branch 1 taken 20 times.
823094 if ((item_equal = cond_equal.current_level.pop())) {
4241
2/4
✓ Branch 0 taken 823042 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 823042 times.
823040 if (item_equal->resolve_type(thd)) return true;
4242
1/2
✓ Branch 0 taken 823085 times.
✗ Branch 1 not taken.
823042 item_equal->update_used_tables();
4243 1646084 thd->lex->current_query_block()->max_equal_elems =
4244 822994 std::max(thd->lex->current_query_block()->max_equal_elems,
4245
1/2
✓ Branch 0 taken 822998 times.
✗ Branch 1 not taken.
823085 item_equal->members());
4246 823024 *retcond = item_equal;
4247 823024 return false;
4248 }
4249
4250 20 *retcond = eq_list.pop();
4251 return false;
4252 } else {
4253 /*
4254 Here a new AND level must be created. It can happen only
4255 when a row equality is processed as a standalone predicate.
4256 */
4257
2/4
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 68 times.
✗ Branch 3 not taken.
64 Item_cond_and *and_cond = new Item_cond_and(eq_list);
4258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
68 if (and_cond == nullptr) return true;
4259
4260 68 and_cond->quick_fix_field();
4261 68 List<Item> *args = and_cond->argument_list();
4262
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 List_iterator_fast<Item_equal> it(cond_equal.current_level);
4263
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 68 times.
208 while ((item_equal = it++)) {
4264
2/4
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 140 times.
140 if (item_equal->resolve_type(thd)) return true;
4265
1/2
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
140 item_equal->update_used_tables();
4266 280 thd->lex->current_query_block()->max_equal_elems =
4267 140 std::max(thd->lex->current_query_block()->max_equal_elems,
4268
1/2
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
280 item_equal->members());
4269 }
4270
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 and_cond->cond_equal = cond_equal;
4271
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 args->concat((List<Item> *)&cond_equal.current_level);
4272
4273 68 *retcond = and_cond;
4274 68 return false;
4275 }
4276 }
4277
4278
2/2
✓ Branch 0 taken 1864389 times.
✓ Branch 1 taken 47 times.
1864436 if (do_inherit) {
4279 /*
4280 For each field reference in cond, not from equal item predicates,
4281 set a pointer to the multiple equality it belongs to (if there is any)
4282 as soon the field is not of a string type or the field reference is
4283 an argument of a comparison predicate.
4284 */
4285 1864389 uchar *is_subst_valid = (uchar *)1;
4286
1/2
✓ Branch 0 taken 1864439 times.
✗ Branch 1 not taken.
1864389 cond = cond->compile(&Item::subst_argument_checker, &is_subst_valid,
4287 &Item::equal_fields_propagator, (uchar *)inherited);
4288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1864439 times.
1864439 if (cond == nullptr) return true;
4289 }
4290
1/2
✓ Branch 0 taken 1864430 times.
✗ Branch 1 not taken.
1864486 cond->update_used_tables();
4291 }
4292 3713746 *retcond = cond;
4293 3713746 return false;
4294 }
4295
4296 /**
4297 Build multiple equalities for a WHERE condition and all join conditions that
4298 inherit these multiple equalities.
4299
4300 The function first applies the build_equal_items_for_cond function
4301 to build all multiple equalities for condition cond utilizing equalities
4302 referred through the parameter inherited. The extended set of
4303 equalities is returned in the structure referred by the cond_equal_ref
4304 parameter. After this the function calls itself recursively for
4305 all join conditions whose direct references can be found in join_list
4306 and who inherit directly the multiple equalities just having built.
4307
4308 @note
4309 The join condition used in an outer join operation inherits all equalities
4310 from the join condition of the embedding join, if there is any, or
4311 otherwise - from the where condition.
4312 This fact is not obvious, but presumably can be proved.
4313 Consider the following query:
4314 @code
4315 SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t2.a=t4.a
4316 WHERE t1.a=t2.a;
4317 @endcode
4318 If the join condition in the query inherits =(t1.a,t2.a), then we
4319 can build the multiple equality =(t1.a,t2.a,t3.a,t4.a) that infers
4320 the equality t3.a=t4.a. Although the join condition
4321 t1.a=t3.a AND t2.a=t4.a AND t3.a=t4.a is not equivalent to the one
4322 in the query the latter can be replaced by the former: the new query
4323 will return the same result set as the original one.
4324
4325 Interesting that multiple equality =(t1.a,t2.a,t3.a,t4.a) allows us
4326 to use t1.a=t3.a AND t3.a=t4.a under the join condition:
4327 @code
4328 SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a
4329 WHERE t1.a=t2.a
4330 @endcode
4331 This query equivalent to:
4332 @code
4333 SELECT * FROM (t1 LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a),t2
4334 WHERE t1.a=t2.a
4335 @endcode
4336 Similarly the original query can be rewritten to the query:
4337 @code
4338 SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t2.a=t4.a AND t3.a=t4.a
4339 WHERE t1.a=t2.a
4340 @endcode
4341 that is equivalent to:
4342 @code
4343 SELECT * FROM (t2 LEFT JOIN (t3,t4)ON t2.a=t4.a AND t3.a=t4.a), t1
4344 WHERE t1.a=t2.a
4345 @endcode
4346 Thus, applying equalities from the where condition we basically
4347 can get more freedom in performing join operations.
4348 Although we don't use this property now, it probably makes sense to use
4349 it in the future.
4350
4351 @param thd Thread handler
4352 @param cond condition to build the multiple equalities for
4353 @param[out] retcond Returned condition
4354 @param inherited path to all inherited multiple equality items
4355 @param do_inherit whether or not to inherit equalities from other
4356 parts of the condition
4357 @param join_list list of join tables that the condition refers to
4358 @param[out] cond_equal_ref pointer to the structure to place built
4359 equalities in
4360
4361 @returns false if success, true if error
4362 */
4363
4364 2036821 bool build_equal_items(THD *thd, Item *cond, Item **retcond,
4365 COND_EQUAL *inherited, bool do_inherit,
4366 mem_root_deque<TABLE_LIST *> *join_list,
4367 COND_EQUAL **cond_equal_ref) {
4368 2036821 COND_EQUAL *cond_equal = nullptr;
4369
4370
2/2
✓ Branch 0 taken 2031528 times.
✓ Branch 1 taken 5293 times.
2036821 if (cond) {
4371
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2031538 times.
2031528 if (build_equal_items_for_cond(thd, cond, &cond, inherited, do_inherit))
4372 1 return true;
4373 2031538 cond->update_used_tables();
4374 // update_used_tables() returns void but can still fail.
4375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2031621 times.
2031617 if (thd->is_error()) return true;
4376
4377 2031621 const enum Item::Type cond_type = cond->type();
4378
4/4
✓ Branch 0 taken 883574 times.
✓ Branch 1 taken 1147985 times.
✓ Branch 2 taken 860776 times.
✓ Branch 3 taken 1170800 times.
2915150 if (cond_type == Item::COND_ITEM &&
4379
2/2
✓ Branch 0 taken 860810 times.
✓ Branch 1 taken 22781 times.
883574 down_cast<Item_cond *>(cond)->functype() == Item_func::COND_AND_FUNC)
4380 860776 cond_equal = &down_cast<Item_cond_and *>(cond)->cond_equal;
4381
4/4
✓ Branch 0 taken 1147376 times.
✓ Branch 1 taken 23424 times.
✓ Branch 2 taken 810063 times.
✓ Branch 3 taken 360669 times.
2318108 else if (cond_type == Item::FUNC_ITEM &&
4382
2/2
✓ Branch 0 taken 810007 times.
✓ Branch 1 taken 337301 times.
1147376 down_cast<Item_func *>(cond)->functype() ==
4383 Item_func::MULT_EQUAL_FUNC) {
4384
2/4
✓ Branch 0 taken 810092 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 810101 times.
✗ Branch 3 not taken.
810063 cond_equal = new (thd->mem_root) COND_EQUAL;
4385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 810101 times.
810101 if (cond_equal == nullptr) return true;
4386 810101 cond_equal->current_level.push_back(down_cast<Item_equal *>(cond));
4387 }
4388 }
4389
2/2
✓ Branch 0 taken 1670882 times.
✓ Branch 1 taken 366105 times.
2036987 if (cond_equal) {
4390 1670882 cond_equal->upper_levels = inherited;
4391 1670882 inherited = cond_equal;
4392 }
4393 2036987 *cond_equal_ref = cond_equal;
4394
4395
2/2
✓ Branch 0 taken 1515060 times.
✓ Branch 1 taken 521927 times.
2036987 if (join_list) {
4396
7/12
✓ Branch 0 taken 1515050 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1515062 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3569862 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3569852 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5084848 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3569834 times.
✓ Branch 11 taken 1515014 times.
5084877 for (TABLE_LIST *table : *join_list) {
4397
2/2
✓ Branch 0 taken 525109 times.
✓ Branch 1 taken 3044711 times.
3569862 if (table->join_cond_optim()) {
4398 525109 mem_root_deque<TABLE_LIST *> *nested_join_list =
4399
2/2
✓ Branch 0 taken 3252 times.
✓ Branch 1 taken 521857 times.
525109 table->nested_join ? &table->nested_join->join_list : nullptr;
4400 Item *join_cond;
4401
2/4
✓ Branch 0 taken 525100 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 525100 times.
525109 if (build_equal_items(thd, table->join_cond_optim(), &join_cond,
4402 inherited, do_inherit, nested_join_list,
4403 &table->cond_equal))
4404 return true;
4405 525100 table->set_join_cond_optim(join_cond);
4406 }
4407 }
4408 }
4409
4410 2036941 *retcond = cond;
4411 2036941 return false;
4412 }
4413
4414 /**
4415 Compare field items by table order in the execution plan.
4416
4417 field1 considered as better than field2 if the table containing
4418 field1 is accessed earlier than the table containing field2.
4419 The function finds out what of two fields is better according
4420 this criteria.
4421
4422 @param field1 first field item to compare
4423 @param field2 second field item to compare
4424 @param table_join_idx index to tables determining table order
4425
4426 @retval
4427 -1 if field1 is better than field2
4428 @retval
4429 1 if field2 is better than field1
4430 @retval
4431 0 otherwise
4432 */
4433
4434 2589961 static int compare_fields_by_table_order(Item_field *field1, Item_field *field2,
4435 JOIN_TAB **table_join_idx) {
4436 2589961 int cmp = 0;
4437 2589961 bool outer_ref = false;
4438
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2590056 times.
2589961 if (field1->is_outer_reference()) {
4439 outer_ref = true;
4440 cmp = -1;
4441 }
4442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2590069 times.
2590056 if (field2->is_outer_reference()) {
4443 outer_ref = true;
4444 cmp++;
4445 }
4446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2590069 times.
2590069 if (outer_ref) return cmp;
4447
4448 /*
4449 table_join_idx is NULL if this function was not called from JOIN::optimize()
4450 but from e.g. mysql_delete() or mysql_update(). In these cases
4451 there is only one table and both fields belong to it. Example
4452 condition where this is the case: t1.fld1=t1.fld2
4453 */
4454
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 2589860 times.
2590069 if (!table_join_idx) return 0;
4455
4456 // Locate JOIN_TABs thanks to table_join_idx, then compare their index.
4457 2589860 cmp = table_join_idx[field1->table_ref->tableno()]->idx() -
4458 2589798 table_join_idx[field2->table_ref->tableno()]->idx();
4459
4/4
✓ Branch 0 taken 1238298 times.
✓ Branch 1 taken 1351561 times.
✓ Branch 2 taken 1233331 times.
✓ Branch 3 taken 4967 times.
2589859 return cmp < 0 ? -1 : (cmp ? 1 : 0);
4460 }
4461
4462 /**
4463 Generate minimal set of simple equalities equivalent to a multiple equality.
4464
4465 The function retrieves the fields of the multiple equality item
4466 item_equal and for each field f:
4467 - if item_equal contains const it generates the equality f=const_item;
4468 - otherwise, if f is not the first field, generates the equality
4469 f=item_equal->get_first().
4470 All generated equality are added to the cond conjunction.
4471
4472 @param thd the session context
4473 @param cond condition to add the generated equality to
4474 @param upper_levels structure to access multiple equality of upper levels
4475 @param item_equal multiple equality to generate simple equality from
4476
4477 @note
4478 Before generating an equality function checks that it has not
4479 been generated for multiple equalities of the upper levels.
4480 E.g. for the following where condition
4481 WHERE a=5 AND ((a=b AND b=c) OR c>4)
4482 the upper level AND condition will contain =(5,a),
4483 while the lower level AND condition will contain =(5,a,b,c).
4484 When splitting =(5,a,b,c) into a separate equality predicates
4485 we should omit 5=a, as we have it already in the upper level.
4486 The following where condition gives us a more complicated case:
4487 WHERE t1.a=t2.b AND t3.c=t4.d AND (t2.b=t3.c OR t4.e>5 ...) AND ...
4488 Given the tables are accessed in the order t1->t2->t3->t4 for
4489 the selected query execution plan the lower level multiple
4490 equality =(t1.a,t2.b,t3.c,t4.d) formally should be converted to
4491 t1.a=t2.b AND t1.a=t3.c AND t1.a=t4.d. But t1.a=t2.a will be
4492 generated for the upper level. Also t3.c=t4.d will be generated there.
4493 So only t1.a=t3.c should be left in the lower level.
4494 If cond is equal to 0, then not more then one equality is generated
4495 and a pointer to it is returned as the result of the function.
4496
4497 @return
4498 - The condition with generated simple equalities or
4499 a pointer to the simple generated equality, if success.
4500 - 0, otherwise.
4501 */
4502
4503 4998995 static Item *eliminate_item_equal(THD *thd, Item *cond,
4504 COND_EQUAL *upper_levels,
4505 Item_equal *item_equal) {
4506 4998995 List<Item> eq_list;
4507 4999033 Item *eq_item = nullptr;
4508
7/10
✓ Branch 0 taken 4999055 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1644 times.
✓ Branch 3 taken 4997411 times.
✓ Branch 4 taken 1644 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1644 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1644 times.
✓ Branch 9 taken 4997411 times.
4999033 if (((Item *)item_equal)->const_item() && !item_equal->val_int())
4509
1/2
✓ Branch 0 taken 1644 times.
✗ Branch 1 not taken.
3288 return new Item_func_false();
4510 4997411 Item *const item_const = item_equal->get_const();
4511
1/2
✓ Branch 0 taken 4997340 times.
✗ Branch 1 not taken.
4997414 auto it = item_equal->get_fields().begin();
4512
2/2
✓ Branch 0 taken 1958196 times.
✓ Branch 1 taken 3039144 times.
4997340 if (!item_const) {
4513 /*
4514 If there is a const item, match all field items with the const item,
4515 otherwise match the second and subsequent field items with the first one:
4516 */
4517 1958196 it++;
4518 }
4519
4/6
✓ Branch 0 taken 10087635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10087612 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5090174 times.
✓ Branch 5 taken 4997438 times.
10087682 while (it != item_equal->get_fields().end()) {
4520 /*
4521 Generate an equality of the form:
4522 item_field = some previous field in item_equal's list.
4523
4524 First see if we really need to generate it:
4525 */
4526 5090174 Item_field *item_field = &*it++; // Field to generate equality for.
4527
1/2
✓ Branch 0 taken 5090086 times.
✗ Branch 1 not taken.
5090101 Item_equal *const upper = item_field->find_item_equal(upper_levels);
4528
2/2
✓ Branch 0 taken 157583 times.
✓ Branch 1 taken 4932503 times.
5090086 if (upper) // item_field is in this upper equality
4529 {
4530
6/6
✓ Branch 0 taken 156675 times.
✓ Branch 1 taken 908 times.
✓ Branch 2 taken 156301 times.
✓ Branch 3 taken 372 times.
✓ Branch 4 taken 156306 times.
✓ Branch 5 taken 1275 times.
157583 if (item_const && upper->get_const())
4531 156306 continue; // Const at both levels, no need to generate at current level
4532 /*
4533 If the upper-level multiple equality contains this item, there is no
4534 need to generate the equality, unless item_field belongs to a
4535 semi-join nest that is used for Materialization, and refers to tables
4536 that are outside of the materialized semi-join nest,
4537 As noted in Item_equal::get_subst_item(), subquery materialization
4538 does not have this problem.
4539 */
4540 1275 JOIN_TAB *const tab = item_field->field->table->reginfo.join_tab;
4541
4542
6/8
✓ Branch 0 taken 1292 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1167 times.
✓ Branch 5 taken 125 times.
✓ Branch 6 taken 1150 times.
✓ Branch 7 taken 125 times.
1275 if (!(tab && sj_is_materialize_strategy(tab->get_sj_strategy()))) {
4543 Item_field *item_match;
4544
1/2
✓ Branch 0 taken 1150 times.
✗ Branch 1 not taken.
1150 auto li = item_equal->get_fields().begin();
4545
2/2
✓ Branch 0 taken 992 times.
✓ Branch 1 taken 158 times.
1150 while ((item_match = &*li++) != item_field) {
4546
2/4
✓ Branch 0 taken 992 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 992 times.
✗ Branch 3 not taken.
992 if (item_match->find_item_equal(upper_levels) == upper)
4547 992 break; // (item_match, item_field) is also in upper level equality
4548 }
4549
2/2
✓ Branch 0 taken 992 times.
✓ Branch 1 taken 158 times.
1150 if (item_match != item_field) continue;
4550 }
4551 } // ... if (upper).
4552
4553 /*
4554 item_field should be compared with the head of the multiple equality
4555 list.
4556 item_field may refer to a table that is within a semijoin materialization
4557 nest. In that case, the order of the join_tab entries may look like:
4558
4559 ot1 ot2 <subquery> ot5 SJM(it3 it4)
4560
4561 If we have a multiple equality
4562
4563 (ot1.c1, ot2.c2, <subquery>.c it3.c3, it4.c4, ot5.c5),
4564
4565 we should generate the following equalities:
4566 1. ot1.c1 = ot2.c2
4567 2. ot1.c1 = <subquery>.c
4568 3. it3.c3 = it4.c4
4569 4. ot1.c1 = ot5.c5
4570
4571 Equalities 1) and 4) are regular equalities between two outer tables.
4572 Equality 2) is an equality that matches the outer query with a
4573 materialized temporary table. It is either performed as a lookup
4574 into the materialized table (SJM-lookup), or as a condition on the
4575 outer table (SJM-scan).
4576 Equality 3) is evaluated during semijoin materialization.
4577
4578 If there is a const item, match against this one.
4579 Otherwise, match against the first field item in the multiple equality,
4580 unless the item is within a materialized semijoin nest, in case it will
4581 be matched against the first item within the SJM nest.
4582 @see JOIN::set_prefix_tables()
4583 @see Item_equal::get_subst_item()
4584 */
4585
4586 Item *const head =
4587
3/4
✓ Branch 0 taken 1990278 times.
✓ Branch 1 taken 2942508 times.
✓ Branch 2 taken 1990229 times.
✗ Branch 3 not taken.
4932786 item_const ? item_const : item_equal->get_subst_item(item_field);
4588
2/2
✓ Branch 0 taken 3221 times.
✓ Branch 1 taken 4929516 times.
4932737 if (head == item_field) continue;
4589
4590 // we have a pair, can generate 'item_field=head'
4591
3/4
✓ Branch 0 taken 32605 times.
✓ Branch 1 taken 4896911 times.
✓ Branch 2 taken 32605 times.
✗ Branch 3 not taken.
4929516 if (eq_item) eq_list.push_back(eq_item);
4592
4593
3/4
✓ Branch 0 taken 4929619 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1987542 times.
✓ Branch 3 taken 2942077 times.
4929516 if (head->type() == Item::FIELD_ITEM) {
4594 // Store away all fields that were considered equal, so that we are able
4595 // to undo this operation later if we have to. See
4596 // Item_func::ensure_multi_equality_fields_are_available for more details.
4597 1987542 Item_field *head_field = down_cast<Item_field *>(head);
4598 1987573 head_field->set_item_equal_all_join_nests(item_equal);
4599 }
4600
2/4
✓ Branch 0 taken 4929607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4929638 times.
✗ Branch 3 not taken.
4929638 eq_item = new Item_func_eq(item_field, head);
4601
4602
6/8
✓ Branch 0 taken 4929653 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4929690 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 4929674 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 4929674 times.
4929638 if (!eq_item || down_cast<Item_func_eq *>(eq_item)->set_cmp_func())
4603 1 return nullptr;
4604
4605 4929674 eq_item->quick_fix_field();
4606
2/2
✓ Branch 0 taken 2942573 times.
✓ Branch 1 taken 1987058 times.
4929631 if (item_const != nullptr) {
4607
1/2
✓ Branch 0 taken 2942599 times.
✗ Branch 1 not taken.
2942573 eq_item->apply_is_true();
4608 Item::cond_result res;
4609
2/4
✓ Branch 0 taken 2942777 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2942777 times.
2942599 if (fold_condition(thd, eq_item, &eq_item, &res)) return nullptr;
4610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2942777 times.
2942777 if (res == Item::COND_FALSE) {
4611 eq_item = new (thd->mem_root) Item_func_false();
4612 if (eq_item == nullptr) return nullptr;
4613 return eq_item; // entire AND is false
4614
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2942777 times.
2942777 } else if (res == Item::COND_TRUE) {
4615 eq_item = new (thd->mem_root) Item_func_true();
4616 if (eq_item == nullptr) return nullptr;
4617 }
4618 }
4619 } // ... while ((item_field= it++))
4620
4621
6/6
✓ Branch 0 taken 825590 times.
✓ Branch 1 taken 4171848 times.
✓ Branch 2 taken 817903 times.
✓ Branch 3 taken 7637 times.
✓ Branch 4 taken 817913 times.
✓ Branch 5 taken 4179475 times.
4997438 if (!cond && !eq_list.head()) {
4622
3/4
✓ Branch 0 taken 59308 times.
✓ Branch 1 taken 758605 times.
✓ Branch 2 taken 59308 times.
✗ Branch 3 not taken.
877221 if (!eq_item) return new Item_func_true();
4623 758605 return eq_item;
4624 }
4625
4626
3/4
✓ Branch 0 taken 4138538 times.
✓ Branch 1 taken 40937 times.
✓ Branch 2 taken 4138538 times.
✗ Branch 3 not taken.
4179475 if (eq_item) eq_list.push_back(eq_item);
4627
2/2
✓ Branch 0 taken 7634 times.
✓ Branch 1 taken 4171841 times.
4179475 if (!cond)
4628
2/4
✓ Branch 0 taken 7634 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7634 times.
✗ Branch 3 not taken.
7634 cond = new Item_cond_and(eq_list);
4629 else {
4630
2/4
✓ Branch 0 taken 4171841 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4171841 times.
4171841 assert(cond->type() == Item::COND_ITEM);
4631
3/4
✓ Branch 0 taken 4130868 times.
✓ Branch 1 taken 40973 times.
✓ Branch 2 taken 4130896 times.
✗ Branch 3 not taken.
4171841 if (eq_list.elements) ((Item_cond *)cond)->add_at_head(&eq_list);
4632 }
4633
4634 4179503 cond->quick_fix_field();
4635
1/2
✓ Branch 0 taken 4179534 times.
✗ Branch 1 not taken.
4179510 cond->update_used_tables();
4636
4637 4179534 return cond;
4638 }
4639
4640 /**
4641 Substitute every field reference in a condition by the best equal field
4642 and eliminate all multiple equality predicates.
4643
4644 The function retrieves the cond condition and for each encountered
4645 multiple equality predicate it sorts the field references in it
4646 according to the order of tables specified by the table_join_idx
4647 parameter. Then it eliminates the multiple equality predicate by
4648 replacing it with the conjunction of simple equality predicates
4649 equating every field from the multiple equality to the first
4650 field in it, or to the constant, if there is any.
4651 After this, the function retrieves all other conjuncted
4652 predicates and substitutes every field reference by the field reference
4653 to the first equal field or equal constant if there are any.
4654
4655 @param thd the session context
4656 @param cond condition to process
4657 @param cond_equal multiple equalities to take into consideration
4658 @param table_join_idx index to tables determining field preference
4659
4660 @note
4661 At the first glance, a full sort of fields in multiple equality
4662 seems to be an overkill. Yet it's not the case due to possible
4663 new fields in multiple equality item of lower levels. We want
4664 the order in them to comply with the order of upper levels.
4665
4666 @return
4667 The transformed condition, or NULL in case of error
4668 */
4669
4670 4416713 Item *substitute_for_best_equal_field(THD *thd, Item *cond,
4671 COND_EQUAL *cond_equal,
4672 JOIN_TAB **table_join_idx) {
4673
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4416840 times.
4416713 assert(cond->is_bool_func());
4674
2/2
✓ Branch 0 taken 1797156 times.
✓ Branch 1 taken 2619720 times.
4416840 if (cond->type() == Item::COND_ITEM) {
4675 1797156 List<Item> *cond_list = ((Item_cond *)cond)->argument_list();
4676
4677 bool and_level =
4678
1/2
✓ Branch 0 taken 1797134 times.
✗ Branch 1 not taken.
1797131 ((Item_cond *)cond)->functype() == Item_func::COND_AND_FUNC;
4679
2/2
✓ Branch 0 taken 1773473 times.
✓ Branch 1 taken 23661 times.
1797134 if (and_level) {
4680 1773473 cond_equal = &((Item_cond_and *)cond)->cond_equal;
4681 1773473 cond_list->disjoin((List<Item> *)&cond_equal->current_level);
4682
4683
1/2
✓ Branch 0 taken 1773511 times.
✗ Branch 1 not taken.
1773494 List_iterator_fast<Item_equal> it(cond_equal->current_level);
4684 1749823 auto cmp = [table_join_idx](Item_field *f1, Item_field *f2) {
4685 1749823 return compare_fields_by_table_order(f1, f2, table_join_idx);
4686 1773511 };
4687 Item_equal *item_equal;
4688
2/2
✓ Branch 0 taken 4173456 times.
✓ Branch 1 taken 1773524 times.
5946936 while ((item_equal = it++)) {
4689
1/2
✓ Branch 0 taken 4173425 times.
✗ Branch 1 not taken.
4173456 item_equal->sort(cmp);
4690 }
4691 }
4692
4693
1/2
✓ Branch 0 taken 1797165 times.
✗ Branch 1 not taken.
1797185 List_iterator<Item> li(*cond_list);
4694 Item *item;
4695
2/2
✓ Branch 0 taken 2449075 times.
✓ Branch 1 taken 1797163 times.
4246214 while ((item = li++)) {
4696
1/2
✓ Branch 0 taken 2449049 times.
✗ Branch 1 not taken.
2449075 Item *new_item = substitute_for_best_equal_field(thd, item, cond_equal,
4697 table_join_idx);
4698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2449049 times.
2449049 if (new_item == nullptr) return nullptr;
4699 /*
4700 This works OK with PS/SP re-execution as changes are made to
4701 the arguments of AND/OR items only
4702 */
4703
2/2
✓ Branch 0 taken 12805 times.
✓ Branch 1 taken 2436244 times.
2449049 if (new_item != item) li.replace(new_item);
4704 }
4705
4706
2/2
✓ Branch 0 taken 1773521 times.
✓ Branch 1 taken 23642 times.
1797163 if (and_level) {
4707
1/2
✓ Branch 0 taken 1773521 times.
✗ Branch 1 not taken.
1773521 List_iterator_fast<Item_equal> it(cond_equal->current_level);
4708 Item_equal *item_equal;
4709
2/2
✓ Branch 0 taken 4173451 times.
✓ Branch 1 taken 1771957 times.
5945421 while ((item_equal = it++)) {
4710
1/2
✓ Branch 0 taken 4173455 times.
✗ Branch 1 not taken.
4173451 cond = eliminate_item_equal(thd, cond, cond_equal->upper_levels,
4711 item_equal);
4712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4173455 times.
4173455 if (cond == nullptr) return nullptr;
4713 // This occurs when eliminate_item_equal() founds that cond is
4714 // always false and substitutes it with a false value.
4715 // Due to this, value of item_equal will be 0, so just return it.
4716
3/4
✓ Branch 0 taken 4173463 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1563 times.
✓ Branch 3 taken 4171900 times.
4173455 if (cond->type() != Item::COND_ITEM) break;
4717 }
4718 }
4719
5/6
✓ Branch 0 taken 1797166 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1795604 times.
✓ Branch 3 taken 1562 times.
✓ Branch 4 taken 15584 times.
✓ Branch 5 taken 1781580 times.
3592764 if (cond->type() == Item::COND_ITEM &&
4720
2/2
✓ Branch 0 taken 15584 times.
✓ Branch 1 taken 1780018 times.
1795604 !((Item_cond *)cond)->argument_list()->elements)
4721
3/6
✓ Branch 0 taken 15584 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15584 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15584 times.
✗ Branch 5 not taken.
31168 cond = cond->val_bool() ? implicit_cast<Item *>(new Item_func_true())
4722 : implicit_cast<Item *>(new Item_func_false());
4723
4/4
✓ Branch 0 taken 2619082 times.
✓ Branch 1 taken 502 times.
✓ Branch 2 taken 825629 times.
✓ Branch 3 taken 1794106 times.
5238953 } else if (cond->type() == Item::FUNC_ITEM &&
4724
2/2
✓ Branch 0 taken 825636 times.
✓ Branch 1 taken 1793597 times.
2619082 (down_cast<Item_func *>(cond))->functype() ==
4725 Item_func::MULT_EQUAL_FUNC) {
4726 825629 Item_equal *item_equal = down_cast<Item_equal *>(cond);
4727 825677 item_equal->sort([table_join_idx](Item_field *f1, Item_field *f2) {
4728 840150 return compare_fields_by_table_order(f1, f2, table_join_idx);
4729 });
4730
6/6
✓ Branch 0 taken 819507 times.
✓ Branch 1 taken 6042 times.
✓ Branch 2 taken 811786 times.
✓ Branch 3 taken 7788 times.
✓ Branch 4 taken 811758 times.
✓ Branch 5 taken 13858 times.
825549 if (cond_equal && cond_equal->current_level.head() == item_equal)
4731 811758 cond_equal = cond_equal->upper_levels;
4732 825616 return eliminate_item_equal(thd, nullptr, cond_equal, item_equal);
4733 } else {
4734 1794106 uchar *dummy = nullptr;
4735
1/2
✓ Branch 0 taken 1794106 times.
✗ Branch 1 not taken.
1794106 if (cond->compile(&Item::visit_all_analyzer, &dummy,
4736
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1794106 times.
1794106 &Item::replace_equal_field, nullptr) == nullptr)
4737 return nullptr;
4738 }
4739 3591270 return cond;
4740 }
4741
4742 /**
4743 change field = field to field = const for each found field = const in the
4744 and_level
4745
4746 @param thd Thread handler
4747 @param save_list saved list of COND_CMP
4748 @param and_father father of AND op
4749 @param cond Condition where fields are replaced with constant values
4750 @param field The field that will be substituted
4751 @param value The substitution value
4752
4753 @returns false if success, true if error
4754 */
4755
4756 500560 static bool change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
4757 Item *and_father, Item *cond, Item *field,
4758 Item *value) {
4759
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 500560 times.
500560 assert(cond->real_item()->is_bool_func());
4760
2/2
✓ Branch 0 taken 134564 times.
✓ Branch 1 taken 365996 times.
500560 if (cond->type() == Item::COND_ITEM) {
4761 134564 Item_cond *const item_cond = down_cast<Item_cond *>(cond);
4762
1/2
✓ Branch 0 taken 134564 times.
✗ Branch 1 not taken.
134564 bool and_level = item_cond->functype() == Item_func::COND_AND_FUNC;
4763
1/2
✓ Branch 0 taken 134564 times.
✗ Branch 1 not taken.
134564 List_iterator<Item> li(*item_cond->argument_list());
4764 Item *item;
4765
2/2
✓ Branch 0 taken 366497 times.
✓ Branch 1 taken 134564 times.
501061 while ((item = li++)) {
4766
4/6
✓ Branch 0 taken 365507 times.
✓ Branch 1 taken 990 times.
✓ Branch 2 taken 366497 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 366497 times.
366497 if (change_cond_ref_to_const(thd, save_list, and_level ? cond : item,
4767 item, field, value))
4768 return true;
4769 }
4770 134564 return false;
4771 }
4772
2/2
✓ Branch 0 taken 126969 times.
✓ Branch 1 taken 239027 times.
365996 if (cond->eq_cmp_result() == Item::COND_OK)
4773 126969 return false; // Not a boolean function
4774
4775 239027 Item_bool_func2 *func = down_cast<Item_bool_func2 *>(cond);
4776 239027 Item **args = func->arguments();
4777 239027 Item *left_item = args[0];
4778 239027 Item *right_item = args[1];
4779 239027 Item_func::Functype functype = func->functype();
4780
4781
2/2
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 232 times.
239369 if (right_item->eq(field, false) && left_item != value &&
4782
5/6
✓ Branch 0 taken 342 times.
✓ Branch 1 taken 238685 times.
✓ Branch 2 taken 110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 110 times.
✓ Branch 5 taken 238917 times.
239479 right_item->cmp_context == field->cmp_context &&
4783
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 95 times.
110 (left_item->result_type() != STRING_RESULT ||
4784
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 value->result_type() != STRING_RESULT ||
4785
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 left_item->collation.collation == value->collation.collation)) {
4786 110 Item *const clone = value->clone_item();
4787
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 110 times.
110 if (thd->is_error()) return true;
4788
4789
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 84 times.
110 if (clone == nullptr) return false;
4790
4791 84 clone->collation.set(right_item->collation);
4792 84 thd->change_item_tree(args + 1, clone);
4793 84 func->update_used_tables();
4794
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 47 times.
✓ Branch 3 taken 27 times.
84 if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
4795
6/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 74 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 44 times.
✓ Branch 5 taken 40 times.
168 and_father != cond && !left_item->const_item()) {
4796 44 cond->marker = Item::MARKER_CONST_PROPAG;
4797
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 COND_CMP *const cond_cmp = new COND_CMP(and_father, func);
4798
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
44 if (cond_cmp == nullptr) return true;
4799
4800 44 save_list->push_back(cond_cmp);
4801 }
4802
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if (func->set_cmp_func()) return true;
4803
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 133746 times.
372698 } else if (left_item->eq(field, false) && right_item != value &&
4804
5/6
✓ Branch 0 taken 133781 times.
✓ Branch 1 taken 105136 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 238883 times.
372733 left_item->cmp_context == field->cmp_context &&
4805
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 9 times.
35 (right_item->result_type() != STRING_RESULT ||
4806
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 value->result_type() != STRING_RESULT ||
4807
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
26 right_item->collation.collation == value->collation.collation)) {
4808 34 Item *const clone = value->clone_item();
4809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if (thd->is_error()) return true;
4810
4811
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if (clone == nullptr) return false;
4812
4813 34 clone->collation.set(left_item->collation);
4814 34 thd->change_item_tree(args, clone);
4815 34 value = clone;
4816 34 func->update_used_tables();
4817
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
34 if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
4818
6/6
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 26 times.
68 and_father != cond && !right_item->const_item()) {
4819 8 args[0] = args[1]; // For easy check
4820 8 thd->change_item_tree(args + 1, value);
4821 8 cond->marker = Item::MARKER_CONST_PROPAG;
4822
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 COND_CMP *const cond_cmp = new COND_CMP(and_father, func);
4823
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (cond_cmp == nullptr) return true;
4824
4825 8 save_list->push_back(cond_cmp);
4826 }
4827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if (func->set_cmp_func()) return true;
4828 }
4829 239001 return false;
4830 }
4831
4832 /**
4833 Propagate constant values in a condition
4834
4835 @param thd Thread handler
4836 @param save_list saved list of COND_CMP
4837 @param and_father father of AND op
4838 @param cond Condition for which constant values are propagated
4839
4840 @returns false if success, true if error
4841 */
4842 7923404 static bool propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
4843 Item *and_father, Item *cond) {
4844
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7923464 times.
7923404 assert(cond->real_item()->is_bool_func());
4845
2/2
✓ Branch 0 taken 1694712 times.
✓ Branch 1 taken 6228795 times.
7923464 if (cond->type() == Item::COND_ITEM) {
4846 1694712 Item_cond *const item_cond = down_cast<Item_cond *>(cond);
4847
1/2
✓ Branch 0 taken 1694597 times.
✗ Branch 1 not taken.
1694609 bool and_level = item_cond->functype() == Item_func::COND_AND_FUNC;
4848
1/2
✓ Branch 0 taken 1694608 times.
✗ Branch 1 not taken.
1694597 List_iterator_fast<Item> li(*item_cond->argument_list());
4849 Item *item;
4850
1/2
✓ Branch 0 taken 1694567 times.
✗ Branch 1 not taken.
1694608 I_List<COND_CMP> save;
4851
2/2
✓ Branch 0 taken 6406818 times.
✓ Branch 1 taken 1694592 times.
8101385 while ((item = li++)) {
4852
5/6
✓ Branch 0 taken 5378512 times.
✓ Branch 1 taken 1028306 times.
✓ Branch 2 taken 6406819 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 6406818 times.
6406818 if (propagate_cond_constants(thd, &save, and_level ? cond : item, item))
4853 1 return true;
4854 }
4855
2/2
✓ Branch 0 taken 1663620 times.
✓ Branch 1 taken 30972 times.
1694592 if (and_level) { // Handle other found items
4856
1/2
✓ Branch 0 taken 1663623 times.
✗ Branch 1 not taken.
1663620 I_List_iterator<COND_CMP> cond_itr(save);
4857 COND_CMP *cond_cmp;
4858
3/4
✓ Branch 0 taken 1663669 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 1663617 times.
1663675 while ((cond_cmp = cond_itr++)) {
4859
1/2
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
52 Item **args = cond_cmp->cmp_func->arguments();
4860
3/6
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 52 times.
104 if (!args[0]->const_item() &&
4861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 change_cond_ref_to_const(thd, &save, cond_cmp->and_level,
4862
1/2
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
52 cond_cmp->and_level, args[0], args[1]))
4863 return true;
4864 }
4865 }
4866
2/2
✓ Branch 0 taken 5370237 times.
✓ Branch 1 taken 858558 times.
6228795 } else if (and_father != cond &&
4867
2/2
✓ Branch 0 taken 5370215 times.
✓ Branch 1 taken 22 times.
5370237 cond->marker != Item::MARKER_CONST_PROPAG) // In a AND group
4868 {
4869 Item_func *func;
4870
1/2
✓ Branch 0 taken 5369938 times.
✗ Branch 1 not taken.
10740145 if (cond->type() == Item::FUNC_ITEM &&
4871
4/4
✓ Branch 0 taken 5369899 times.
✓ Branch 1 taken 322 times.
✓ Branch 2 taken 173296 times.
✓ Branch 3 taken 5196947 times.
10740142 (func = down_cast<Item_func *>(cond)) &&
4872
2/2
✓ Branch 0 taken 5196772 times.
✓ Branch 1 taken 173146 times.
5369938 (func->functype() == Item_func::EQ_FUNC ||
4873
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 5196633 times.
5196772 func->functype() == Item_func::EQUAL_FUNC)) {
4874 173296 Item **args = func->arguments();
4875 173296 bool left_const = args[0]->const_item();
4876 173296 bool right_const = args[1]->const_item();
4877
6/6
✓ Branch 0 taken 625 times.
✓ Branch 1 taken 172671 times.
✓ Branch 2 taken 248 times.
✓ Branch 3 taken 377 times.
✓ Branch 4 taken 167109 times.
✓ Branch 5 taken 6187 times.
346215 if (!(left_const && right_const) &&
4878
2/2
✓ Branch 0 taken 167109 times.
✓ Branch 1 taken 5810 times.
172919 args[0]->result_type() == args[1]->result_type()) {
4879
2/2
✓ Branch 0 taken 133768 times.
✓ Branch 1 taken 33341 times.
167109 if (right_const) {
4880 133768 Item *item = args[1];
4881
3/4
✓ Branch 0 taken 133768 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 133767 times.
133768 if (resolve_const_item(thd, &item, args[0])) return true;
4882
1/2
✓ Branch 0 taken 133767 times.
✗ Branch 1 not taken.
133767 thd->change_item_tree(&args[1], item);
4883
1/2
✓ Branch 0 taken 133767 times.
✗ Branch 1 not taken.
133767 func->update_used_tables();
4884
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133767 times.
133767 if (change_cond_ref_to_const(thd, save_list, and_father, and_father,
4885
1/2
✓ Branch 0 taken 133767 times.
✗ Branch 1 not taken.
133767 args[0], args[1]))
4886 return true;
4887
2/2
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 33097 times.
33341 } else if (left_const) {
4888 244 Item *item = args[0];
4889
2/4
✓ Branch 0 taken 244 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 244 times.
244 if (resolve_const_item(thd, &item, args[1])) return true;
4890
1/2
✓ Branch 0 taken 244 times.
✗ Branch 1 not taken.
244 thd->change_item_tree(&args[0], item);
4891
1/2
✓ Branch 0 taken 244 times.
✗ Branch 1 not taken.
244 func->update_used_tables();
4892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 244 times.
244 if (change_cond_ref_to_const(thd, save_list, and_father, and_father,
4893
1/2
✓ Branch 0 taken 244 times.
✗ Branch 1 not taken.
244 args[1], args[0]))
4894 return true;
4895 }
4896 }
4897 }
4898 }
4899
4900 7923411 return false;
4901 }
4902
4903 /**
4904 Assign each nested join structure a bit in nested_join_map.
4905
4906 @param join_list List of tables
4907 @param first_unused Number of first unused bit in nested_join_map before the
4908 call
4909
4910 @note
4911 This function is called after simplify_joins(), when there are no
4912 redundant nested joins.
4913 We cannot have more nested joins in a query block than there are tables,
4914 so as long as the number of bits in nested_join_map is not less than the
4915 maximum number of tables in a query block, nested_join_map can never
4916 overflow.
4917
4918 @return
4919 First unused bit in nested_join_map after the call.
4920 */
4921
4922 13809526 uint build_bitmap_for_nested_joins(mem_root_deque<TABLE_LIST *> *join_list,
4923 uint first_unused) {
4924
1/2
✓ Branch 0 taken 13810241 times.
✗ Branch 1 not taken.
13809526 DBUG_TRACE;
4925
7/12
✓ Branch 0 taken 13810218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13810232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3729363 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3729364 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 17539076 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3729357 times.
✓ Branch 11 taken 13809719 times.
17539604 for (TABLE_LIST *table : *join_list) {
4926 NESTED_JOIN *nested_join;
4927
2/2
✓ Branch 0 taken 24689 times.
✓ Branch 1 taken 3704674 times.
3729363 if ((nested_join = table->nested_join)) {
4928 // We should have a join condition or a semi-join condition or both
4929
3/4
✓ Branch 0 taken 21347 times.
✓ Branch 1 taken 3342 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21347 times.
24689 assert((table->join_cond() != nullptr) || table->is_sj_nest());
4930
4931 24689 nested_join->nj_map = 0;
4932 24689 nested_join->nj_total = 0;
4933 /*
4934 We only record nested join information for outer join nests.
4935 Tables belonging in semi-join nests are recorded in the
4936 embedding outer join nest, if one exists.
4937 */
4938
2/2
✓ Branch 0 taken 3342 times.
✓ Branch 1 taken 21347 times.
24689 if (table->join_cond()) {
4939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3342 times.
3342 assert(first_unused < sizeof(nested_join_map) * 8);
4940 3342 nested_join->nj_map = (nested_join_map)1 << first_unused++;
4941 3342 nested_join->nj_total = nested_join->join_list.size();
4942
1/2
✓ Branch 0 taken 21347 times.
✗ Branch 1 not taken.
21347 } else if (table->is_sj_nest()) {
4943 21347 NESTED_JOIN *const outer_nest =
4944
2/2
✓ Branch 0 taken 890 times.
✓ Branch 1 taken 20457 times.
21347 table->embedding ? table->embedding->nested_join : nullptr;
4945 /*
4946 The semi-join nest has already been counted into the table count
4947 for the outer join nest as one table, so subtract 1 from the
4948 table count.
4949 */
4950
2/2
✓ Branch 0 taken 890 times.
✓ Branch 1 taken 20457 times.
21347 if (outer_nest)
4951 890 outer_nest->nj_total += (nested_join->join_list.size() - 1);
4952 } else
4953 assert(false);
4954
4955 first_unused =
4956
1/2
✓ Branch 0 taken 24689 times.
✗ Branch 1 not taken.
24689 build_bitmap_for_nested_joins(&nested_join->join_list, first_unused);
4957 }
4958 }
4959 13810258 return first_unused;
4960 13809719 }
4961
4962 /** Update the dependency map for the tables. */
4963
4964 1816574 void JOIN::update_depend_map() {
4965
3/6
✓ Branch 0 taken 1816593 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1816597 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1816626 times.
✗ Branch 5 not taken.
1816574 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
4966
2/2
✓ Branch 0 taken 6257593 times.
✓ Branch 1 taken 1816670 times.
8074263 for (uint tableno = 0; tableno < tables; tableno++) {
4967 6257593 JOIN_TAB *const tab = best_ref[tableno];
4968 6257593 TABLE_REF *const ref = &tab->ref();
4969 6257627 table_map depend_map = 0;
4970 6257627 Item **item = ref->items;
4971
2/2
✓ Branch 0 taken 2457922 times.
✓ Branch 1 taken 6257651 times.
8715573 for (uint i = 0; i < ref->key_parts; i++, item++)
4972 2457922 depend_map |= (*item)->used_tables();
4973 6257651 depend_map &= ~PSEUDO_TABLE_BITS;
4974 6257651 ref->depend_map = depend_map;
4975
2/2
✓ Branch 0 taken 3807824 times.
✓ Branch 1 taken 6257656 times.
10065480 for (JOIN_TAB **tab2 = map2table; depend_map; tab2++, depend_map >>= 1) {
4976
2/2
✓ Branch 0 taken 1845456 times.
✓ Branch 1 taken 1962368 times.
3807824 if (depend_map & 1) ref->depend_map |= (*tab2)->ref().depend_map;
4977 }
4978 }
4979 1816670 }
4980
4981 /** Update the dependency map for the sort order. */
4982
4983 3464417 void JOIN::update_depend_map(ORDER *order) {
4984
1/2
✓ Branch 0 taken 3464465 times.
✗ Branch 1 not taken.
3464417 DBUG_TRACE;
4985
2/2
✓ Branch 0 taken 893923 times.
✓ Branch 1 taken 3464465 times.
4358388 for (; order; order = order->next) {
4986 table_map depend_map;
4987
1/2
✓ Branch 0 taken 893923 times.
✗ Branch 1 not taken.
893923 order->item[0]->update_used_tables();
4988 893923 order->depend_map = depend_map =
4989
1/2
✓ Branch 0 taken 893923 times.
✗ Branch 1 not taken.
893923 order->item[0]->used_tables() & ~INNER_TABLE_BIT;
4990 893923 order->used = 0;
4991 // Not item_sum(), RAND() and no reference to table outside of sub select
4992
4/4
✓ Branch 0 taken 893567 times.
✓ Branch 1 taken 356 times.
✓ Branch 2 taken 893222 times.
✓ Branch 3 taken 701 times.
1787490 if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)) &&
4993
2/2
✓ Branch 0 taken 893222 times.
✓ Branch 1 taken 345 times.
893567 !order->item[0]->has_aggregation()) {
4994
2/2
✓ Branch 0 taken 1182320 times.
✓ Branch 1 taken 893222 times.
2075542 for (JOIN_TAB **tab = map2table; depend_map; tab++, depend_map >>= 1) {
4995
2/2
✓ Branch 0 taken 944686 times.
✓ Branch 1 taken 237634 times.
1182320 if (depend_map & 1) order->depend_map |= (*tab)->ref().depend_map;
4996 }
4997 }
4998 }
4999 3464465 }
5000
5001 /**
5002 Update equalities and keyuse references after semi-join materialization
5003 strategy is chosen.
5004
5005 @details
5006 For each multiple equality that contains a field that is selected
5007 from a subquery, and that subquery is executed using a semi-join
5008 materialization strategy, add the corresponding column in the materialized
5009 temporary table to the equality.
5010 For each injected semi-join equality that is not converted to
5011 multiple equality, replace the reference to the expression selected
5012 from the subquery with the corresponding column in the temporary table.
5013
5014 This is needed to properly reflect the equalities that involve injected
5015 semi-join equalities when materialization strategy is chosen.
5016 @see eliminate_item_equal() for how these equalities are used to generate
5017 correct equality predicates.
5018
5019 The MaterializeScan semi-join strategy requires some additional processing:
5020 All primary tables after the materialized temporary table must be inspected
5021 for keyuse objects that point to expressions from the subquery tables.
5022 These references must be replaced with references to corresponding columns
5023 in the materialized temporary table instead. Those primary tables using
5024 ref access will thus be made to depend on the materialized temporary table
5025 instead of the subquery tables.
5026
5027 Only the injected semi-join equalities need this treatment, other predicates
5028 will be handled correctly by the regular item substitution process.
5029
5030 @return False if success, true if error
5031 */
5032
5033 19226 bool JOIN::update_equalities_for_sjm() {
5034
3/6
✓ Branch 0 taken 19226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19226 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19226 times.
✗ Branch 5 not taken.
19226 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
5035
1/2
✓ Branch 0 taken 19226 times.
✗ Branch 1 not taken.
19226 List_iterator<Semijoin_mat_exec> sj_it(sjm_exec_list);
5036 Semijoin_mat_exec *sjm_exec;
5037
2/2
✓ Branch 0 taken 4591 times.
✓ Branch 1 taken 19226 times.
23817 while ((sjm_exec = sj_it++)) {
5038 4591 TABLE_LIST *const sj_nest = sjm_exec->sj_nest;
5039
5040 Item *cond;
5041 /*
5042 Conditions involving SJ-inner tables are only to be found in the closest
5043 nest's condition, which may be an AJ nest, a LEFT JOIN nest, or the
5044 WHERE clause.
5045 */
5046
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 4538 times.
4591 if (sj_nest->is_aj_nest())
5047 53 cond = sj_nest->join_cond_optim();
5048
2/2
✓ Branch 0 taken 275 times.
✓ Branch 1 taken 4263 times.
4538 else if (sj_nest->outer_join_nest())
5049 275 cond = sj_nest->outer_join_nest()->join_cond_optim();
5050 else
5051 4263 cond = where_cond;
5052
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 4542 times.
4591 if (!cond) continue;
5053
5054 4542 uchar *dummy = nullptr;
5055
1/2
✓ Branch 0 taken 4542 times.
✗ Branch 1 not taken.
4542 cond = cond->compile(&Item::equality_substitution_analyzer, &dummy,
5056 &Item::equality_substitution_transformer,
5057 (uchar *)sj_nest);
5058
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4542 times.
4542 if (cond == nullptr) return true;
5059
5060
1/2
✓ Branch 0 taken 4542 times.
✗ Branch 1 not taken.
4542 cond->update_used_tables();
5061
5062 // Loop over all primary tables that follow the materialized table
5063
2/2
✓ Branch 0 taken 3243 times.
✓ Branch 1 taken 4542 times.
7785 for (uint j = sjm_exec->mat_table_index + 1; j < primary_tables; j++) {
5064 3243 JOIN_TAB *const tab = best_ref[j];
5065 4748 for (Key_use *keyuse = tab->position()->key;
5066
6/6
✓ Branch 0 taken 2902 times.
✓ Branch 1 taken 1846 times.
✓ Branch 2 taken 1535 times.
✓ Branch 3 taken 1367 times.
✓ Branch 4 taken 1505 times.
✓ Branch 5 taken 3243 times.
6283 keyuse && keyuse->table_ref == tab->table_ref &&
5067
2/2
✓ Branch 0 taken 1505 times.
✓ Branch 1 taken 30 times.
1535 keyuse->key == tab->position()->key->key;
5068 keyuse++) {
5069 1505 uint fieldno = 0;
5070
6/10
✓ Branch 0 taken 1505 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1505 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1568 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1999 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1568 times.
✓ Branch 9 taken 431 times.
1999 for (Item *old : sj_nest->nested_join->sj_inner_exprs) {
5071
5/8
✓ Branch 0 taken 1568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1568 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1568 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1074 times.
✓ Branch 7 taken 494 times.
1568 if (old->real_item()->eq(keyuse->val->real_item(), false)) {
5072 /*
5073 Replace the expression selected from the subquery with the
5074 corresponding column of the materialized temporary table.
5075 */
5076 1074 keyuse->val = sj_nest->nested_join->sjm.mat_fields[fieldno];
5077
1/2
✓ Branch 0 taken 1074 times.
✗ Branch 1 not taken.
1074 keyuse->used_tables = keyuse->val->used_tables();
5078 1074 break;
5079 }
5080
1/2
✓ Branch 0 taken 494 times.
✗ Branch 1 not taken.
494 fieldno++;
5081 }
5082 }
5083 }
5084 }
5085
5086 19226 return false;
5087 }
5088
5089 /**
5090 Assign set of available (prefix) tables to all tables in query block.
5091 Also set added tables, ie the tables added in each JOIN_TAB compared to the
5092 previous JOIN_TAB.
5093 This function must be called for every query block after the table order
5094 has been determined.
5095 */
5096
5097 1767388 void JOIN::set_prefix_tables() {
5098
3/6
✓ Branch 0 taken 1767402 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1767427 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1767452 times.
✗ Branch 5 not taken.
1767388 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
5099
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1767455 times.
1767438 assert(!plan_is_const());
5100 /*
5101 The const tables are available together with the first non-const table in
5102 the join order.
5103 */
5104 1767455 table_map const initial_tables_map =
5105
2/2
✓ Branch 0 taken 1765355 times.
✓ Branch 1 taken 2100 times.
1767455 const_table_map | (allow_outer_refs ? OUTER_REF_TABLE_BIT : 0);
5106
5107 1767455 table_map current_tables_map = initial_tables_map;
5108 1767455 table_map prev_tables_map = (table_map)0;
5109 1767455 table_map saved_tables_map = (table_map)0;
5110
5111 1767455 JOIN_TAB *last_non_sjm_tab = nullptr; // Track the last non-sjm table
5112
5113
2/2
✓ Branch 0 taken 6150689 times.
✓ Branch 1 taken 1767511 times.
7918200 for (uint i = const_tables; i < tables; i++) {
5114 6150689 JOIN_TAB *const tab = best_ref[i];
5115
2/2
✓ Branch 0 taken 2335355 times.
✓ Branch 1 taken 3815383 times.
6150689 if (!tab->table()) continue;
5116 /*
5117 Tables that are within SJ-Materialization nests cannot have their
5118 conditions referring to preceding non-const tables.
5119 - If we're looking at the first SJM table, reset current_tables_map
5120 to refer to only allowed tables
5121 @see Item_equal::get_subst_item()
5122 @see eliminate_item_equal()
5123 */
5124
2/2
✓ Branch 0 taken 8459 times.
✓ Branch 1 taken 3806892 times.
3815383 if (sj_is_materialize_strategy(tab->get_sj_strategy())) {
5125 8459 const table_map sjm_inner_tables = tab->emb_sj_nest->sj_inner_tables;
5126
2/2
✓ Branch 0 taken 4591 times.
✓ Branch 1 taken 3868 times.
8459 if (!(sjm_inner_tables & current_tables_map)) {
5127 4591 saved_tables_map = current_tables_map;
5128 4591 current_tables_map = initial_tables_map;
5129 4591 prev_tables_map = (table_map)0;
5130 }
5131
5132 8459 current_tables_map |= tab->table_ref->map();
5133 8459 tab->set_prefix_tables(current_tables_map, prev_tables_map);
5134 8459 prev_tables_map = current_tables_map;
5135
5136
2/2
✓ Branch 0 taken 4591 times.
✓ Branch 1 taken 3868 times.
8459 if (!(sjm_inner_tables & ~current_tables_map)) {
5137 /*
5138 At the end of a semi-join materialization nest,
5139 add non-deterministic expressions to the last table of the nest:
5140 */
5141 4591 tab->add_prefix_tables(RAND_TABLE_BIT);
5142
5143 // Restore the previous map:
5144 4591 current_tables_map = saved_tables_map;
5145 4591 prev_tables_map =
5146
1/2
✓ Branch 0 taken 4591 times.
✗ Branch 1 not taken.
4591 last_non_sjm_tab ? last_non_sjm_tab->prefix_tables() : (table_map)0;
5147 }
5148 } else {
5149 3806892 last_non_sjm_tab = tab;
5150 3806892 current_tables_map |= tab->table_ref->map();
5151 3806876 tab->set_prefix_tables(current_tables_map, prev_tables_map);
5152 3806931 prev_tables_map = current_tables_map;
5153 }
5154 }
5155 /*
5156 Non-deterministic expressions must be added to the last table's condition.
5157 It solves problem with queries like SELECT * FROM t1 WHERE rand() > 0.5
5158 */
5159
2/2
✓ Branch 0 taken 1767481 times.
✓ Branch 1 taken 30 times.
1767511 if (last_non_sjm_tab != nullptr)
5160 1767481 last_non_sjm_tab->add_prefix_tables(RAND_TABLE_BIT);
5161 1767506 }
5162
5163 /**
5164 Calculate best possible join order and initialize the join structure.
5165
5166 @return true if success, false if error.
5167
5168 The JOIN object is populated with statistics about the query,
5169 and a plan with table order and access method selection is made.
5170
5171 The list of tables to be optimized is taken from query_block->leaf_tables.
5172 JOIN::where_cond is also used in the optimization.
5173 As a side-effect, JOIN::keyuse_array is populated with key_use information.
5174
5175 Here is an overview of the logic of this function:
5176
5177 - Initialize JOIN data structures and setup basic dependencies between tables.
5178
5179 - Update dependencies based on join information.
5180
5181 - Make key descriptions (update_ref_and_keys()).
5182
5183 - Pull out semi-join tables based on table dependencies.
5184
5185 - Extract tables with zero or one rows as const tables.
5186
5187 - Read contents of const tables, substitute columns from these tables with
5188 actual data. Also keep track of empty tables vs. one-row tables.
5189
5190 - After const table extraction based on row count, more tables may
5191 have become functionally dependent. Extract these as const tables.
5192
5193 - Add new sargable predicates based on retrieved const values.
5194
5195 - Calculate number of rows to be retrieved from each table.
5196
5197 - Calculate cost of potential semi-join materializations.
5198
5199 - Calculate best possible join order based on available statistics.
5200
5201 - Fill in remaining information for the generated join order.
5202 */
5203
5204 1866955 bool JOIN::make_join_plan() {
5205
1/2
✓ Branch 0 taken 1866986 times.
✗ Branch 1 not taken.
1866955 DBUG_TRACE;
5206
5207 1866986 SARGABLE_PARAM *sargables = nullptr;
5208
5209 1866986 Opt_trace_context *const trace = &thd->opt_trace;
5210
5211
3/4
✓ Branch 0 taken 1866988 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1866986 times.
1866986 if (init_planner_arrays()) // Create and initialize the arrays
5212 2 return true;
5213
5214 // Outer join dependencies were initialized above, now complete the analysis.
5215
6/6
✓ Branch 0 taken 1671716 times.
✓ Branch 1 taken 195270 times.
✓ Branch 2 taken 494 times.
✓ Branch 3 taken 1671222 times.
✓ Branch 4 taken 195764 times.
✓ Branch 5 taken 1671222 times.
1866986 if (query_block->outer_join || query_block->is_recursive()) {
5216
3/4
✓ Branch 0 taken 195755 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 195751 times.
195764 if (propagate_dependencies()) {
5217 /*
5218 Catch illegal join order.
5219 SQL2011 forbids:
5220 WITH RECURSIVE rec AS (
5221 ... UNION ALL SELECT ... FROM tbl LEFT JOIN rec ON...)c...
5222 MySQL also forbids the same query with STRAIGHT_JOIN instead of LEFT
5223 JOIN, because the algorithm of with-recursive imposes that "rec" be
5224 first in plan, i.e. "tbl" depends on "rec", but STRAIGHT_JOIN imposes
5225 the opposite dependency.
5226 */
5227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 assert(query_block->is_recursive());
5228 4 my_error(ER_CTE_RECURSIVE_FORBIDDEN_JOIN_ORDER, MYF(0),
5229
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 query_block->recursive_reference->alias);
5230 4 return true;
5231 }
5232 195751 init_key_dependencies();
5233 }
5234
5235
2/2
✓ Branch 0 taken 2711 times.
✓ Branch 1 taken 1864255 times.
1866967 if (unlikely(trace->is_started()))
5236
1/2
✓ Branch 0 taken 2711 times.
✗ Branch 1 not taken.
2711 trace_table_dependencies(trace, join_tab, primary_tables);
5237
5238 // Build the key access information, which is the basis for ref access.
5239
4/4
✓ Branch 0 taken 631787 times.
✓ Branch 1 taken 1235179 times.
✓ Branch 2 taken 5671 times.
✓ Branch 3 taken 626116 times.
1866966 if (where_cond || query_block->outer_join) {
5240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1240838 times.
1240838 if (update_ref_and_keys(thd, &keyuse_array, join_tab, tables, where_cond,
5241
1/2
✓ Branch 0 taken 1240838 times.
✗ Branch 1 not taken.
1240850 ~query_block->outer_join, query_block, &sargables))
5242 return true;
5243 }
5244
5245 /*
5246 Pull out semi-join tables based on dependencies. Dependencies are valid
5247 throughout the lifetime of a query, so this operation can be performed
5248 on the first optimization only.
5249 */
5250
6/8
✓ Branch 0 taken 1755767 times.
✓ Branch 1 taken 111187 times.
✓ Branch 2 taken 1755767 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20542 times.
✓ Branch 5 taken 1735225 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1866954 times.
1887496 if (!query_block->sj_pullout_done && !query_block->sj_nests.empty() &&
5251
2/4
✓ Branch 0 taken 20542 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20542 times.
20542 pull_out_semijoin_tables(this))
5252 return true;
5253
5254 1866954 query_block->sj_pullout_done = true;
5255 1866954 const uint sj_nests = query_block->sj_nests.size(); // Changed by pull-out
5256
5257
2/2
✓ Branch 0 taken 1860869 times.
✓ Branch 1 taken 6080 times.
1866929 if (!(query_block->active_options() & OPTION_NO_CONST_TABLES)) {
5258 // Detect tables that are const (0 or 1 row) and read their contents.
5259
2/4
✓ Branch 0 taken 1860915 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1860915 times.
1860869 if (extract_const_tables()) return true;
5260
5261 // Detect tables that are functionally dependent on const values.
5262
3/4
✓ Branch 0 taken 1860912 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 1860862 times.
1860915 if (extract_func_dependent_tables()) return true;
5263 }
5264 // Possibly able to create more sargable predicates from const rows.
5265
5/6
✓ Branch 0 taken 127380 times.
✓ Branch 1 taken 1739562 times.
✓ Branch 2 taken 118985 times.
✓ Branch 3 taken 8395 times.
✓ Branch 4 taken 118985 times.
✗ Branch 5 not taken.
1866942 if (const_tables && sargables) update_sargable_from_const(sargables);
5266
5267 // Make a first estimate of the fanout for each table in the query block.
5268
2/4
✓ Branch 0 taken 1866921 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1866921 times.
1866942 if (estimate_rowcount()) return true;
5269
5270 /*
5271 Apply join order hints, with the exception of
5272 JOIN_FIXED_ORDER and STRAIGHT_JOIN.
5273 */
5274
4/4
✓ Branch 0 taken 7618 times.
✓ Branch 1 taken 1859303 times.
✓ Branch 2 taken 7613 times.
✓ Branch 3 taken 1859308 times.
1874539 if (query_block->opt_hints_qb &&
5275
2/2
✓ Branch 0 taken 7613 times.
✓ Branch 1 taken 5 times.
7618 !(query_block->active_options() & SELECT_STRAIGHT_JOIN))
5276
1/2
✓ Branch 0 taken 7613 times.
✗ Branch 1 not taken.
7613 query_block->opt_hints_qb->apply_join_order_hints(this);
5277
5278
2/2
✓ Branch 0 taken 19232 times.
✓ Branch 1 taken 1847689 times.
1866921 if (sj_nests) {
5279
1/2
✓ Branch 0 taken 19232 times.
✗ Branch 1 not taken.
19232 set_semijoin_embedding();
5280
1/2
✓ Branch 0 taken 19232 times.
✗ Branch 1 not taken.
19232 query_block->update_semijoin_strategies(thd);
5281 }
5282
5283
3/4
✓ Branch 0 taken 1767448 times.
✓ Branch 1 taken 99396 times.
✓ Branch 2 taken 1767507 times.
✗ Branch 3 not taken.
1866921 if (!plan_is_const()) optimize_keyuse();
5284
5285 1866903 allow_outer_refs = true;
5286
5287
5/8
✓ Branch 0 taken 19232 times.
✓ Branch 1 taken 1847671 times.
✓ Branch 2 taken 19232 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19232 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1866903 times.
1866903 if (sj_nests && optimize_semijoin_nests_for_materialization(this))
5288 return true;
5289
5290 // Choose the table order based on analysis done so far.
5291
4/6
✓ Branch 0 taken 1866917 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1866934 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 1866925 times.
1866903 if (Optimize_table_order(thd, this, nullptr).choose_table_order())
5292 9 return true;
5293
5294
3/4
✓ Branch 0 taken 1866918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1866916 times.
1866925 DBUG_EXECUTE_IF("bug13820776_1", thd->killed = THD::KILL_QUERY;);
5295
6/8
✓ Branch 0 taken 1866924 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1866913 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 1866883 times.
✓ Branch 6 taken 22 times.
✓ Branch 7 taken 1866883 times.
1866918 if (thd->killed || thd->is_error()) return true;
5296
5297 // If this is a subquery, decide between In-to-exists and materialization
5298
7/8
✓ Branch 0 taken 106041 times.
✓ Branch 1 taken 1760848 times.
✓ Branch 2 taken 106041 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 106032 times.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 1866880 times.
1866883 if (query_expression()->item && decide_subquery_strategy()) return true;
5299
5300
1/2
✓ Branch 0 taken 1866819 times.
✗ Branch 1 not taken.
1866880 refine_best_rowcount();
5301
5302 3733953 if (!(thd->variables.option_bits & OPTION_BIG_SELECTS) &&
5303
6/6
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 1866504 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 303 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 1866807 times.
1866831 best_read > (double)thd->variables.max_join_size &&
5304
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 !thd->lex->is_explain()) { /* purecov: inspected */
5305
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 my_error(ER_TOO_BIG_SELECT, MYF(0));
5306 12 error = -1;
5307 12 return true;
5308 }
5309
5310 1866807 positions = nullptr; // But keep best_positions for get_best_combination
5311
5312 // Generate an execution plan from the found optimal join order.
5313
2/4
✓ Branch 0 taken 1866880 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1866880 times.
1866807 if (get_best_combination()) return true;
5314
5315 // Cleanup after update_ref_and_keys has added keys for derived tables.
5316
3/4
✓ Branch 0 taken 177564 times.
✓ Branch 1 taken 1689316 times.
✓ Branch 2 taken 177564 times.
✗ Branch 3 not taken.
1866880 if (query_block->materialized_derived_table_count) finalize_derived_keys();
5317
5318 // No need for this struct after new JOIN_TAB array is set up.
5319 1866880 best_positions = nullptr;
5320
5321 // Some called function may still set error status unnoticed
5322
2/4
✓ Branch 0 taken 1866882 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1866882 times.
1866880 if (thd->is_error()) return true;
5323
5324 // There is at least one empty const table
5325
2/2
✓ Branch 0 taken 50202 times.
✓ Branch 1 taken 1816680 times.
1866882 if (const_table_map != found_const_table_map)
5326 50202 zero_result_cause = "no matching row in const table";
5327
5328 1866882 return false;
5329 1866990 }
5330
5331 /**
5332 Initialize scratch arrays for the join order optimization
5333
5334 @returns false if success, true if error
5335
5336 @note If something fails during initialization, JOIN::cleanup()
5337 will free anything that has been partially allocated and set up.
5338 Arrays are created in the execution mem_root, so they will be
5339 deleted automatically when the mem_root is re-initialized.
5340 */
5341
5342 1866941 bool JOIN::init_planner_arrays() {
5343 // Up to one extra slot per semi-join nest is needed (if materialized)
5344 1866941 const uint sj_nests = query_block->sj_nests.size();
5345 1866955 const uint table_count = query_block->leaf_table_count;
5346
5347
2/4
✓ Branch 0 taken 1866977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1866982 times.
✗ Branch 3 not taken.
1866955 assert(primary_tables == 0 && tables == 0);
5348
5349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1866979 times.
1866982 if (!(join_tab = alloc_jtab_array(thd, table_count))) return true;
5350
5351 /*
5352 We add 2 cells:
5353 - because planning stage uses 0-termination so needs +1
5354 - because after get_best_combination, we don't use 0-termination but
5355 need +2, to host at most 2 tmp sort/group/distinct tables.
5356 */
5357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1866965 times.
1866965 if (!(best_ref = (JOIN_TAB **)thd->alloc(
5358 sizeof(JOIN_TAB *) *
5359 1866979 (table_count + sj_nests + 2 + m_windows.elements))))
5360 return true;
5361
5362 // sort/group tmp tables have no map
5363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1866973 times.
1866973 if (!(map2table = (JOIN_TAB **)thd->alloc(sizeof(JOIN_TAB *) *
5364 1866965 (table_count + sj_nests))))
5365 return true;
5366
5367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1866978 times.
1866973 if (!(positions = new (thd->mem_root) POSITION[table_count])) return true;
5368
5369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1866979 times.
1866978 if (!(best_positions = new (thd->mem_root) POSITION[table_count + sj_nests]))
5370 return true;
5371
5372 /*
5373 Initialize data structures for tables to be joined.
5374 Initialize dependencies between tables.
5375 */
5376 1866979 JOIN_TAB **best_ref_p = best_ref;
5377 1866979 TABLE_LIST *tl = query_block->leaf_tables;
5378
5379
2/2
✓ Branch 0 taken 3951399 times.
✓ Branch 1 taken 1866974 times.
5818373 for (JOIN_TAB *tab = join_tab; tl; tab++, tl = tl->next_leaf, best_ref_p++) {
5380 3951399 *best_ref_p = tab;
5381 3951399 TABLE *const table = tl->table;
5382 3951399 tab->table_ref = tl;
5383 3951399 tab->set_table(table);
5384 3951387 const int err = tl->fetch_number_of_rows();
5385
5386 // Initialize the cost model for the table
5387 3951425 table->init_cost_model(cost_model());
5388
5389
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3951391 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3951398 DBUG_EXECUTE_IF("bug11747970_raise_error", {
5390 if (!err) {
5391 my_error(ER_UNKNOWN_ERROR, MYF(0));
5392 return true;
5393 }
5394 });
5395
5396
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3951389 times.
3951391 if (err) {
5397 2 table->file->print_error(err, MYF(0));
5398 2 return true;
5399 }
5400 3951389 all_table_map |= tl->map();
5401 3951389 tab->set_join(this);
5402
5403
6/6
✓ Branch 0 taken 3893632 times.
✓ Branch 1 taken 57764 times.
✓ Branch 2 taken 2668 times.
✓ Branch 3 taken 3890972 times.
✓ Branch 4 taken 60432 times.
✓ Branch 5 taken 3890972 times.
3951386 if (tl->is_updated() || tl->is_deleted()) {
5404 // As we update or delete rows, we can't read the index
5405 60432 table->no_keyread = true;
5406 }
5407
5408 3951404 tab->dependent = tl->dep_tables; // Initialize table dependencies
5409
2/2
✓ Branch 0 taken 716 times.
✓ Branch 1 taken 3950668 times.
3951404 if (query_block->is_recursive()) {
5410
2/2
✓ Branch 0 taken 215 times.
✓ Branch 1 taken 501 times.
716 if (query_block->recursive_reference != tl)
5411 // Recursive reference must go first
5412 215 tab->dependent |= query_block->recursive_reference->map();
5413 else {
5414 // Recursive reference mustn't use any index
5415 501 table->covering_keys.clear_all();
5416 501 table->keys_in_use_for_group_by.clear_all();
5417 501 table->keys_in_use_for_order_by.clear_all();
5418 }
5419 }
5420
2/2
✓ Branch 0 taken 164664 times.
✓ Branch 1 taken 3786713 times.
3951377 if (tl->schema_table) table->file->stats.records = 2;
5421 3951377 table->quick_condition_rows = table->file->stats.records;
5422
5423 3951377 tab->init_join_cond_ref(tl);
5424
5425
2/2
✓ Branch 0 taken 7347 times.
✓ Branch 1 taken 3944031 times.
3951381 if (tl->outer_join_nest()) {
5426 // tab belongs to a nested join, maybe to several embedding joins
5427 7347 tab->embedding_map = 0;
5428
2/2
✓ Branch 0 taken 9319 times.
✓ Branch 1 taken 7347 times.
16666 for (TABLE_LIST *embedding = tl->embedding; embedding;
5429 9319 embedding = embedding->embedding) {
5430 9319 NESTED_JOIN *const nested_join = embedding->nested_join;
5431 9319 tab->embedding_map |= nested_join->nj_map;
5432 9319 tab->dependent |= embedding->dep_tables;
5433 }
5434
2/2
✓ Branch 0 taken 526237 times.
✓ Branch 1 taken 3417786 times.
3944031 } else if (tab->join_cond()) {
5435 // tab is the only inner table of an outer join
5436 526237 tab->embedding_map = 0;
5437
2/2
✓ Branch 0 taken 5316 times.
✓ Branch 1 taken 526237 times.
531553 for (TABLE_LIST *embedding = tl->embedding; embedding;
5438 5316 embedding = embedding->embedding)
5439 5316 tab->embedding_map |= embedding->nested_join->nj_map;
5440 }
5441
5442
6/6
✓ Branch 0 taken 176134 times.
✓ Branch 1 taken 3775255 times.
✓ Branch 2 taken 564 times.
✓ Branch 3 taken 175575 times.
✓ Branch 4 taken 564 times.
✓ Branch 5 taken 3950830 times.
3951370 if (tl->is_derived() && tl->derived_query_expression()->m_lateral_deps)
5443 564 has_lateral = true;
5444
5445 3951394 tables++; // Count number of initialized tables
5446 }
5447
5448 1866974 primary_tables = tables;
5449 1866974 *best_ref_p = nullptr; // Last element of array must be NULL
5450
5451 1866974 return false;
5452 }
5453
5454 /**
5455 Propagate dependencies between tables due to outer join relations.
5456
5457 @returns false if success, true if error
5458
5459 Build transitive closure for relation 'to be dependent on'.
5460 This will speed up the plan search for many cases with outer joins,
5461 as well as allow us to catch illegal cross references.
5462 Warshall's algorithm is used to build the transitive closure.
5463 As we may restart the outer loop up to 'table_count' times, the
5464 complexity of the algorithm is O((number of tables)^3).
5465 However, most of the iterations will be shortcircuited when
5466 there are no dependencies to propagate.
5467 */
5468
5469 195823 bool JOIN::propagate_dependencies() {
5470
2/2
✓ Branch 0 taken 1210951 times.
✓ Branch 1 taken 195878 times.
1406829 for (uint i = 0; i < tables; i++) {
5471
2/2
✓ Branch 0 taken 676654 times.
✓ Branch 1 taken 534297 times.
1210951 if (!join_tab[i].dependent) continue;
5472
5473 // Add my dependencies to other tables depending on me
5474 uint j;
5475 JOIN_TAB *tab;
5476
2/2
✓ Branch 0 taken 3332300 times.
✓ Branch 1 taken 534326 times.
3866626 for (j = 0, tab = join_tab; j < tables; j++, tab++) {
5477
2/2
✓ Branch 0 taken 339750 times.
✓ Branch 1 taken 2992605 times.
3332300 if (tab->dependent & join_tab[i].table_ref->map()) {
5478 339750 const table_map was_dependent = tab->dependent;
5479 339750 tab->dependent |= join_tab[i].dependent;
5480 /*
5481 If we change dependencies for a table we already have
5482 processed: Redo dependency propagation from this table.
5483 */
5484
4/4
✓ Branch 0 taken 387 times.
✓ Branch 1 taken 339363 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 361 times.
339750 if (i > j && tab->dependent != was_dependent) {
5485 26 i = j - 1;
5486 26 break;
5487 }
5488 }
5489 }
5490 }
5491
5492 195878 JOIN_TAB *const tab_end = join_tab + tables;
5493
2/2
✓ Branch 0 taken 1210897 times.
✓ Branch 1 taken 195802 times.
1406699 for (JOIN_TAB *tab = join_tab; tab < tab_end; tab++) {
5494
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1210821 times.
1210897 if ((tab->dependent & tab->table_ref->map())) return true;
5495 }
5496
5497 195802 return false;
5498 }
5499
5500 /**
5501 Extract const tables based on row counts.
5502
5503 @returns false if success, true if error
5504
5505 This extraction must be done for each execution.
5506 Tables containing exactly zero or one rows are marked as const, but
5507 notice the additional constraints checked below.
5508 Tables that are extracted have their rows read before actual execution
5509 starts and are placed in the beginning of the join_tab array.
5510 Thus, they do not take part in join order optimization process,
5511 which can significantly reduce the optimization time.
5512 The data read from these tables can also be regarded as "constant"
5513 throughout query execution, hence the column values can be used for
5514 additional constant propagation and extraction of const tables based
5515 on eq-ref properties.
5516
5517 The tables are given the type JT_SYSTEM.
5518 */
5519
5520 1860840 bool JOIN::extract_const_tables() {
5521 enum enum_const_table_extraction {
5522 extract_no_table = 0,
5523 extract_empty_table = 1,
5524 extract_const_table = 2
5525 };
5526
5527 1860840 JOIN_TAB *const tab_end = join_tab + tables;
5528
2/2
✓ Branch 0 taken 3944499 times.
✓ Branch 1 taken 1860953 times.
5805452 for (JOIN_TAB *tab = join_tab; tab < tab_end; tab++) {
5529 3944499 TABLE *const table = tab->table();
5530 3944596 TABLE_LIST *const tl = tab->table_ref;
5531 3944596 enum enum_const_table_extraction extract_method = extract_const_table;
5532
5533 3944596 const bool all_partitions_pruned_away = table->all_partitions_pruned_away;
5534
5535
2/2
✓ Branch 0 taken 7314 times.
✓ Branch 1 taken 3937308 times.
3944596 if (tl->outer_join_nest()) {
5536 /*
5537 Table belongs to a nested join, no candidate for const table extraction.
5538 */
5539 7314 extract_method = extract_no_table;
5540
5/6
✓ Branch 0 taken 36288 times.
✓ Branch 1 taken 3901020 times.
✓ Branch 2 taken 36288 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36288 times.
✓ Branch 5 taken 3901020 times.
3937308 } else if (tl->embedding && tl->embedding->is_sj_or_aj_nest()) {
5541 /*
5542 Table belongs to a semi-join.
5543 We do not currently pull out const tables from semi-join nests.
5544 */
5545 36288 extract_method = extract_no_table;
5546
2/2
✓ Branch 0 taken 520661 times.
✓ Branch 1 taken 3380361 times.
3901020 } else if (tab->join_cond()) {
5547 // tab is the only inner table of an outer join, extract empty tables
5548 520661 extract_method = extract_empty_table;
5549 }
5550
4/4
✓ Branch 0 taken 43602 times.
✓ Branch 1 taken 520658 times.
✓ Branch 2 taken 3380331 times.
✓ Branch 3 taken 33 times.
3944624 switch (extract_method) {
5551 43602 case extract_no_table:
5552 43602 break;
5553
5554 520658 case extract_empty_table:
5555 // Extract tables with zero rows, but only if statistics are exact
5556
5/6
✓ Branch 0 taken 520591 times.
✓ Branch 1 taken 67 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 520594 times.
✓ Branch 4 taken 63 times.
✓ Branch 5 taken 520595 times.
520722 if ((table->file->stats.records == 0 || all_partitions_pruned_away) &&
5557
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 1 times.
64 (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT))
5558 63 mark_const_table(tab, nullptr);
5559 520657 break;
5560
5561 3380331 case extract_const_table:
5562 /*
5563 Extract tables with zero or one rows, but do not extract tables that
5564 1. are dependent upon other tables, or
5565 2. have no exact statistics, or
5566 3. are full-text searched
5567 */
5568
3/4
✓ Branch 0 taken 2751730 times.
✓ Branch 1 taken 628561 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2751730 times.
3380291 if ((table->s->system || table->file->stats.records <= 1 ||
5569 628601 all_partitions_pruned_away) &&
5570
2/2
✓ Branch 0 taken 627707 times.
✓ Branch 1 taken 894 times.
628601 !tab->dependent && // 1
5571
6/6
✓ Branch 0 taken 3380291 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 49056 times.
✓ Branch 3 taken 578637 times.
✓ Branch 4 taken 49009 times.
✓ Branch 5 taken 3331300 times.
6809710 (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && // 2
5572
2/2
✓ Branch 0 taken 49009 times.
✓ Branch 1 taken 39 times.
49056 !tl->is_fulltext_searched()) // 3
5573 49009 mark_const_table(tab, nullptr);
5574 3380320 break;
5575 }
5576 }
5577
5578 // Read const tables (tables matching no more than 1 rows)
5579
2/2
✓ Branch 0 taken 1812203 times.
✓ Branch 1 taken 48750 times.
1860953 if (!const_tables) return false;
5580
5581 97822 for (POSITION *p_pos = positions, *p_end = p_pos + const_tables;
5582
2/2
✓ Branch 0 taken 49072 times.
✓ Branch 1 taken 48750 times.
97822 p_pos < p_end; p_pos++) {
5583 49072 JOIN_TAB *const tab = p_pos->table;
5584 49072 const int status = join_read_const_table(tab, p_pos);
5585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49072 times.
49072 if (status > 0)
5586 return true;
5587
2/2
✓ Branch 0 taken 11462 times.
✓ Branch 1 taken 37610 times.
49072 else if (status == 0) {
5588 11462 found_const_table_map |= tab->table_ref->map();
5589 11462 tab->table_ref->optimized_away = true;
5590 }
5591 }
5592
5593 48750 return false;
5594 }
5595
5596 /**
5597 Extract const tables based on functional dependencies.
5598
5599 @returns false if success, true if error
5600
5601 This extraction must be done for each execution.
5602
5603 Mark as const the tables that
5604 - are functionally dependent on constant values, or
5605 - are inner tables of an outer join and contain exactly zero or one rows
5606
5607 Tables that are extracted have their rows read before actual execution
5608 starts and are placed in the beginning of the join_tab array, just as
5609 described for JOIN::extract_const_tables().
5610
5611 The tables are given the type JT_CONST.
5612 */
5613
5614 1860975 bool JOIN::extract_func_dependent_tables() {
5615 // loop until no more const tables are found
5616 bool ref_changed;
5617 // Tables referenced by others; if they're const the others may be too.
5618 table_map found_ref;
5619 do {
5620 1860975 more_const_tables_found:
5621 1860975 ref_changed = false;
5622 1860975 found_ref = 0;
5623
5624 // Loop over all tables that are not already determined to be const
5625
2/2
✓ Branch 0 taken 3895719 times.
✓ Branch 1 taken 1860913 times.
5756632 for (JOIN_TAB **pos = best_ref + const_tables; *pos; pos++) {
5626 3895719 JOIN_TAB *const tab = *pos;
5627 3895719 TABLE *const table = tab->table();
5628 3895794 TABLE_LIST *const tl = tab->table_ref;
5629 /*
5630 If equi-join condition by a key is null rejecting and after a
5631 substitution of a const table the key value happens to be null
5632 then we can state that there are no matches for this equi-join.
5633 */
5634 3895794 Key_use *keyuse = tab->keyuse();
5635
8/8
✓ Branch 0 taken 2499587 times.
✓ Branch 1 taken 1396247 times.
✓ Branch 2 taken 518063 times.
✓ Branch 3 taken 1981530 times.
✓ Branch 4 taken 517849 times.
✓ Branch 5 taken 214 times.
✓ Branch 6 taken 517851 times.
✓ Branch 7 taken 3377989 times.
3895834 if (keyuse && tab->join_cond() && !tab->embedding_map) {
5636 /*
5637 When performing an outer join operation if there are no matching rows
5638 for the single row of the outer table all the inner tables are to be
5639 null complemented and thus considered as constant tables.
5640 Here we apply this consideration to the case of outer join operations
5641 with a single inner table only because the case with nested tables
5642 would require a more thorough analysis.
5643 TODO. Apply single row substitution to null complemented inner tables
5644 for nested outer join operations.
5645 */
5646
2/2
✓ Branch 0 taken 676215 times.
✓ Branch 1 taken 517779 times.
1193994 while (keyuse->table_ref == tl) {
5647 676215 if (!(keyuse->val->used_tables() & ~const_table_map) &&
5648
8/8
✓ Branch 0 taken 156232 times.
✓ Branch 1 taken 520003 times.
✓ Branch 2 taken 57 times.
✓ Branch 3 taken 156127 times.
✓ Branch 4 taken 50 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 44 times.
✓ Branch 7 taken 676143 times.
676285 keyuse->val->is_null() && keyuse->null_rejecting &&
5649
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 44 times.
50 (tl->embedding == nullptr ||
5650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 !tl->embedding->is_sj_or_aj_nest())) {
5651 44 table->set_null_row();
5652 44 table->const_table = true;
5653 44 found_const_table_map |= tl->map();
5654 44 mark_const_table(tab, keyuse);
5655 56 goto more_const_tables_found;
5656 }
5657 676143 keyuse++;
5658 }
5659 }
5660
5661
2/2
✓ Branch 0 taken 538763 times.
✓ Branch 1 taken 3357005 times.
3895768 if (tab->dependent) // If dependent on some table
5662 {
5663 // All dependent tables must be const
5664
2/2
✓ Branch 0 taken 538374 times.
✓ Branch 1 taken 389 times.
538763 if (tab->dependent & ~const_table_map) {
5665 538374 found_ref |= tab->dependent;
5666 538374 continue;
5667 }
5668 /*
5669 Mark a dependent table as constant if
5670 1. it has exactly zero or one rows (it is a system table), and
5671 2. it is not within a nested outer join, and
5672 3. it does not have an expensive outer join condition.
5673 This is because we have to determine whether an outer-joined table
5674 has a real row or a null-extended row in the optimizer phase.
5675 We have no possibility to evaluate its join condition at
5676 execution time, when it is marked as a system table.
5677 */
5678 949 if (table->file->stats.records <= 1L && // 1
5679
4/4
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 44 times.
230 (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && // 1
5680
6/6
✓ Branch 0 taken 151 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 35 times.
✓ Branch 5 taken 374 times.
655 !tl->outer_join_nest() && // 2
5681
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 20 times.
51 !(tab->join_cond() && tab->join_cond()->is_expensive())) // 3
5682 { // system table
5683 35 mark_const_table(tab, nullptr);
5684 const int status =
5685 35 join_read_const_table(tab, positions + const_tables - 1);
5686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (status > 0)
5687 return true;
5688
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 15 times.
35 else if (status == 0)
5689 20 found_const_table_map |= tl->map();
5690 35 continue;
5691 35 }
5692 }
5693
5694 // Check if table can be read by key or table only uses const refs
5695
5696
2/2
✓ Branch 0 taken 1978087 times.
✓ Branch 1 taken 1379193 times.
3357379 if ((keyuse = tab->keyuse())) {
5697
2/2
✓ Branch 0 taken 3133423 times.
✓ Branch 1 taken 1896774 times.
5030197 while (keyuse->table_ref == tl) {
5698 3133423 Key_use *const start_keyuse = keyuse;
5699 3133423 const uint key = keyuse->key;
5700 3133423 tab->keys().set_bit(key); // QQ: remove this ?
5701
5702 3133481 table_map refs = 0;
5703
2/4
✓ Branch 0 taken 3133509 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3133500 times.
✗ Branch 3 not taken.
3133481 Key_map const_ref, eq_part;
5704 do {
5705
7/8
✓ Branch 0 taken 4044451 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4042128 times.
✓ Branch 3 taken 2323 times.
✓ Branch 4 taken 4041273 times.
✓ Branch 5 taken 855 times.
✓ Branch 6 taken 4041269 times.
✓ Branch 7 taken 3182 times.
4044470 if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize) {
5706
2/2
✓ Branch 0 taken 505988 times.
✓ Branch 1 taken 3535281 times.
4041269 if (!((~found_const_table_map) & keyuse->used_tables))
5707 505988 const_ref.set_bit(keyuse->keypart);
5708 else
5709 3535281 refs |= keyuse->used_tables;
5710 4041270 eq_part.set_bit(keyuse->keypart);
5711 }
5712 4044420 keyuse++;
5713
4/4
✓ Branch 0 taken 2066799 times.
✓ Branch 1 taken 1977621 times.
✓ Branch 2 taken 910970 times.
✓ Branch 3 taken 1155829 times.
4044420 } while (keyuse->table_ref == tl && keyuse->key == key);
5714
5715 /*
5716 Extract const tables with proper key dependencies.
5717 Exclude tables that
5718 1. are full-text searched, or
5719 2. are part of nested outer join, or
5720 3. are part of semi-join, or
5721 4. have an expensive outer join condition.
5722 5. are blocked by handler for const table optimize.
5723 6. are not going to be used, typically because they are streamed
5724 instead of materialized
5725 (see Query_expression::can_materialize_directly_into_result()).
5726 */
5727 3133450 if (eq_part.is_prefix(table->key_info[key].user_defined_key_parts) &&
5728
4/4
✓ Branch 0 taken 2251698 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 2251692 times.
✓ Branch 3 taken 40 times.
4503491 !tl->is_fulltext_searched() && // 1
5729 2251698 !tl->outer_join_nest() && // 2
5730
6/6
✓ Branch 0 taken 7553 times.
✓ Branch 1 taken 2244139 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 7546 times.
✓ Branch 4 taken 124 times.
✓ Branch 5 taken 2244019 times.
4495835 !(tl->embedding && tl->embedding->is_sj_or_aj_nest()) && // 3
5731
2/4
✓ Branch 0 taken 124 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 124 times.
✗ Branch 3 not taken.
2244270 !(tab->join_cond() && tab->join_cond()->is_expensive()) && // 4
5732
8/8
✓ Branch 0 taken 2251759 times.
✓ Branch 1 taken 881693 times.
✓ Branch 2 taken 2244114 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2242832 times.
✓ Branch 5 taken 1260 times.
✓ Branch 6 taken 2242834 times.
✓ Branch 7 taken 890607 times.
7629337 !(table->file->ha_table_flags() & HA_BLOCK_CONST_TABLE) && // 5
5733 2244114 table->is_created()) { // 6
5734
2/2
✓ Branch 0 taken 1779502 times.
✓ Branch 1 taken 463332 times.
2242834 if (table->key_info[key].flags & HA_NOSAME) {
5735
2/2
✓ Branch 0 taken 81354 times.
✓ Branch 1 taken 1698158 times.
1779502 if (const_ref == eq_part) { // Found everything for ref.
5736 81354 ref_changed = true;
5737
1/2
✓ Branch 0 taken 81331 times.
✗ Branch 1 not taken.
81354 mark_const_table(tab, start_keyuse);
5738
3/4
✓ Branch 0 taken 81331 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 81311 times.
81331 if (create_ref_for_key(this, tab, start_keyuse,
5739 found_const_table_map))
5740 50 return true;
5741 const int status =
5742
1/2
✓ Branch 0 taken 81311 times.
✗ Branch 1 not taken.
81311 join_read_const_table(tab, positions + const_tables - 1);
5743
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 81281 times.
81311 if (status > 0)
5744 30 return true;
5745
2/2
✓ Branch 0 taken 78603 times.
✓ Branch 1 taken 2678 times.
81281 else if (status == 0)
5746 78603 found_const_table_map |= tl->map();
5747 81281 break;
5748 } else
5749 1698158 found_ref |= refs; // Table is const if all refs are const
5750
2/2
✓ Branch 0 taken 66944 times.
✓ Branch 1 taken 396398 times.
463332 } else if (const_ref == eq_part)
5751 66944 tab->const_keys.set_bit(key);
5752 }
5753 }
5754 }
5755 }
5756 } while
5757 /*
5758 A new const table appeared, that is referenced by others, so re-check
5759 others:
5760 */
5761
4/4
✓ Branch 0 taken 542 times.
✓ Branch 1 taken 1860371 times.
✓ Branch 2 taken 83 times.
✓ Branch 3 taken 459 times.
1860913 ((const_table_map & found_ref) && ref_changed);
5762
5763 1860830 return false;
5764 }
5765
5766 /**
5767 Update info on indexes that can be used for search lookups as
5768 reading const tables may has added new sargable predicates.
5769 */
5770
5771 118985 void JOIN::update_sargable_from_const(SARGABLE_PARAM *sargables) {
5772
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 118985 times.
119065 for (; sargables->field; sargables++) {
5773 80 Field *const field = sargables->field;
5774 80 JOIN_TAB *const tab = field->table->reginfo.join_tab;
5775 80 Key_map possible_keys = field->key_start;
5776 80 possible_keys.intersect(field->table->keys_in_use_for_query);
5777 80 bool is_const = true;
5778
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 80 times.
196 for (uint j = 0; j < sargables->num_values; j++)
5779
1/2
✓ Branch 0 taken 116 times.
✗ Branch 1 not taken.
116 is_const &= sargables->arg_value[j]->const_item();
5780
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 28 times.
80 if (is_const) {
5781 52 tab->const_keys.merge(possible_keys);
5782 52 tab->keys().merge(possible_keys);
5783 }
5784 }
5785 118985 }
5786
5787 3820807 double find_worst_seeks(const TABLE *table, double num_rows,
5788 double table_scan_cost) {
5789 /*
5790 Set a max value for the cost of seek operations we can expect
5791 when using key lookup. This can't be too high as otherwise we
5792 are likely to use table scan.
5793 */
5794 double worst_seeks =
5795
1/2
✓ Branch 0 taken 3820886 times.
✗ Branch 1 not taken.
3820807 min(table->file->worst_seek_times(num_rows / 10), table_scan_cost * 3);
5796
1/2
✓ Branch 0 taken 3820937 times.
✗ Branch 1 not taken.
3820886 const double min_worst_seek = table->file->worst_seek_times(2.0);
5797 3820937 return std::max(worst_seeks, min_worst_seek); // Fix for small tables
5798 }
5799
5800 /**
5801 Estimate the number of matched rows for each joined table.
5802 Set up range scan for tables that have proper predicates.
5803
5804 @returns false if success, true if error
5805 */
5806
5807 1866842 bool JOIN::estimate_rowcount() {
5808 1866842 Opt_trace_context *const trace = &thd->opt_trace;
5809
1/2
✓ Branch 0 taken 1866913 times.
✗ Branch 1 not taken.
1866842 Opt_trace_object trace_wrapper(trace);
5810
1/2
✓ Branch 0 taken 1866919 times.
✗ Branch 1 not taken.
1866913 Opt_trace_array trace_records(trace, "rows_estimation");
5811
5812 1866919 JOIN_TAB *const tab_end = join_tab + tables;
5813
2/2
✓ Branch 0 taken 3951220 times.
✓ Branch 1 taken 1866997 times.
5818217 for (JOIN_TAB *tab = join_tab; tab < tab_end; tab++) {
5814
1/2
✓ Branch 0 taken 3951288 times.
✗ Branch 1 not taken.
3951220 Opt_trace_object trace_table(trace);
5815
1/2
✓ Branch 0 taken 3951272 times.
✗ Branch 1 not taken.
3951288 trace_table.add_utf8_table(tab->table_ref);
5816
6/6
✓ Branch 0 taken 3902145 times.
✓ Branch 1 taken 49110 times.
✓ Branch 2 taken 81322 times.
✓ Branch 3 taken 3820821 times.
✓ Branch 4 taken 130432 times.
✓ Branch 5 taken 3820821 times.
3951272 if (tab->type() == JT_SYSTEM || tab->type() == JT_CONST) {
5817
1/2
✓ Branch 0 taken 130432 times.
✗ Branch 1 not taken.
130432 trace_table.add("rows", 1)
5818
1/2
✓ Branch 0 taken 130432 times.
✗ Branch 1 not taken.
130432 .add("cost", 1)
5819
3/4
✓ Branch 0 taken 49107 times.
✓ Branch 1 taken 81325 times.
✓ Branch 2 taken 130432 times.
✗ Branch 3 not taken.
130432 .add_alnum("table_type",
5820 130432 (tab->type() == JT_SYSTEM) ? "system" : "const")
5821
1/2
✓ Branch 0 taken 130432 times.
✗ Branch 1 not taken.
130432 .add("empty", tab->table()->has_null_row());
5822
5823 // Only one matching row and one block to read
5824 130432 tab->set_records(tab->found_records = 1);
5825
1/2
✓ Branch 0 taken 130432 times.
✗ Branch 1 not taken.
130432 tab->worst_seeks = tab->table()->file->worst_seek_times(1.0);
5826 130432 tab->read_time = tab->worst_seeks;
5827 130432 continue;
5828 }
5829 // Approximate number of found rows and cost to read them
5830 3820821 tab->set_records(tab->found_records = tab->table()->file->stats.records);
5831
1/2
✓ Branch 0 taken 3820828 times.
✗ Branch 1 not taken.
3820793 const Cost_estimate table_scan_time = tab->table()->file->table_scan_cost();
5832 3820828 tab->read_time = table_scan_time.total_cost();
5833
5834 3820939 tab->worst_seeks =
5835
1/2
✓ Branch 0 taken 3820939 times.
✗ Branch 1 not taken.
3820839 find_worst_seeks(tab->table(), tab->found_records, tab->read_time);
5836
5837 /*
5838 Add to tab->const_keys the indexes for which all group fields or
5839 all select distinct fields participate in one index.
5840 Add to tab->skip_scan_keys indexes which can be used for skip
5841 scan access if no aggregates are present.
5842 */
5843
1/2
✓ Branch 0 taken 3820866 times.
✗ Branch 1 not taken.
3820939 add_loose_index_scan_and_skip_scan_keys(this, tab);
5844
5845 /*
5846 Perform range analysis if there are keys it could use (1).
5847 Don't do range analysis if on the inner side of an outer join (2).
5848 Do range analysis if on the inner side of a semi-join (3).
5849 */
5850 3820866 TABLE_LIST *const tl = tab->table_ref;
5851 3820866 if ((!tab->const_keys.is_clear_all() ||
5852
6/6
✓ Branch 0 taken 3356328 times.
✓ Branch 1 taken 464537 times.
✓ Branch 2 taken 36930 times.
✓ Branch 3 taken 3319434 times.
✓ Branch 4 taken 501115 times.
✓ Branch 5 taken 3319786 times.
4322332 !tab->skip_scan_keys.is_clear_all()) && // (1)
5853
2/2
✓ Branch 0 taken 1830 times.
✓ Branch 1 taken 499637 times.
501467 (!tl->embedding || // (2)
5854
3/4
✓ Branch 0 taken 1830 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1478 times.
✓ Branch 3 taken 352 times.
1830 (tl->embedding && tl->embedding->is_sj_or_aj_nest()))) // (3)
5855 {
5856 /*
5857 This call fills tab->range_scan() with the best QUICK access method
5858 possible for this table, and only if it's better than table scan.
5859 It also fills tab->needed_reg.
5860 */
5861
1/2
✓ Branch 0 taken 501115 times.
✗ Branch 1 not taken.
501115 ha_rows records = get_quick_record_count(thd, tab, row_limit);
5862
5863
5/8
✓ Branch 0 taken 10018 times.
✓ Branch 1 taken 491097 times.
✓ Branch 2 taken 10018 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10018 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 501115 times.
501115 if (records == 0 && thd->is_error()) return true;
5864
5865 /*
5866 Check for "impossible range", but make sure that we do not attempt
5867 to mark semi-joined tables as "const" (only semi-joined tables that
5868 are functionally dependent can be marked "const", and subsequently
5869 pulled out of their semi-join nests).
5870 */
5871
5/6
✓ Branch 0 taken 10018 times.
✓ Branch 1 taken 491097 times.
✓ Branch 2 taken 10018 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9975 times.
✓ Branch 5 taken 491140 times.
511133 if (records == 0 && tab->table()->reginfo.impossible_range &&
5872
3/4
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 9975 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 43 times.
10018 (!(tl->embedding && tl->embedding->is_sj_or_aj_nest()))) {
5873 /*
5874 Impossible WHERE condition or join condition
5875 In case of join cond, mark that one empty NULL row is matched.
5876 In case of WHERE, don't set found_const_table_map to get the
5877 caller to abort with a zero row result.
5878 */
5879
1/2
✓ Branch 0 taken 9975 times.
✗ Branch 1 not taken.
9975 mark_const_table(tab, nullptr);
5880 9975 tab->set_type(JT_CONST); // Override setting made in mark_const_table()
5881
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 9969 times.
9975 if (tab->join_cond()) {
5882 // Generate an empty row
5883
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 trace_table.add("returning_empty_null_row", true)
5884
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 .add_alnum("cause", "impossible_on_condition");
5885 6 found_const_table_map |= tl->map();
5886 6 tab->table()->set_null_row(); // All fields are NULL
5887 } else {
5888
2/4
✓ Branch 0 taken 9969 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9969 times.
✗ Branch 3 not taken.
9969 trace_table.add("rows", 0).add_alnum("cause",
5889 "impossible_where_condition");
5890 }
5891 }
5892
2/2
✓ Branch 0 taken 143539 times.
✓ Branch 1 taken 357576 times.
501115 if (records != HA_POS_ERROR) {
5893 143539 tab->found_records = records;
5894
2/2
✓ Branch 0 taken 133509 times.
✓ Branch 1 taken 10030 times.
143539 tab->read_time = tab->range_scan() ? tab->range_scan()->cost : 0.0;
5895 }
5896 } else {
5897
1/2
✓ Branch 0 taken 3319750 times.
✗ Branch 1 not taken.
6639563 Opt_trace_object(trace, "table_scan")
5898
1/2
✓ Branch 0 taken 3319777 times.
✗ Branch 1 not taken.
3319750 .add("rows", tab->found_records)
5899
1/2
✓ Branch 0 taken 3319777 times.
✗ Branch 1 not taken.
3319777 .add("cost", tab->read_time);
5900 }
5901
2/3
✓ Branch 0 taken 3820866 times.
✓ Branch 1 taken 130432 times.
✗ Branch 2 not taken.
3951335 }
5902
5903 1866997 return false;
5904 1866997 }
5905
5906 /**
5907 Set semi-join embedding join nest pointers.
5908
5909 Set pointer to embedding semi-join nest for all semi-joined tables.
5910 This is the closest semi-join or anti-join nest.
5911 Note that this must be done for every table inside all semi-join nests,
5912 even for tables within outer join nests embedded in semi-join nests.
5913 A table can never be part of multiple semi-join nests, hence no
5914 ambiguities can ever occur.
5915 Note also that the pointer is not set for TABLE_LIST objects that
5916 are outer join nests within semi-join nests.
5917 */
5918
5919 19232 void JOIN::set_semijoin_embedding() {
5920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19232 times.
19232 assert(!query_block->sj_nests.empty());
5921
5922 19232 JOIN_TAB *const tab_end = join_tab + primary_tables;
5923
5924
2/2
✓ Branch 0 taken 63904 times.
✓ Branch 1 taken 19232 times.
83136 for (JOIN_TAB *tab = join_tab; tab < tab_end; tab++) {
5925 63904 tab->emb_sj_nest = nullptr;
5926
2/2
✓ Branch 0 taken 41045 times.
✓ Branch 1 taken 63904 times.
104949 for (TABLE_LIST *tl = tab->table_ref; tl->embedding; tl = tl->embedding) {
5927
2/2
✓ Branch 0 taken 38289 times.
✓ Branch 1 taken 2756 times.
41045 if (tl->embedding->is_sj_or_aj_nest()) {
5928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38289 times.
38289 assert(!tab->emb_sj_nest);
5929 38289 tab->emb_sj_nest = tl->embedding;
5930 // Let the up-walk continue, to assert there's no AJ/SJ nest above.
5931 }
5932 }
5933 }
5934 19232 }
5935
5936 /**
5937 @brief Check if semijoin's compared types allow materialization.
5938
5939 @param[in,out] sj_nest Semi-join nest containing information about correlated
5940 expressions. Set nested_join->sjm.scan_allowed to true if
5941 MaterializeScan strategy allowed. Set nested_join->sjm.lookup_allowed
5942 to true if MaterializeLookup strategy allowed
5943
5944 @details
5945 This is a temporary fix for BUG#36752.
5946
5947 There are two subquery materialization strategies for semijoin:
5948
5949 1. Materialize and do index lookups in the materialized table. See
5950 BUG#36752 for description of restrictions we need to put on the
5951 compared expressions.
5952
5953 In addition, since indexes are not supported for BLOB columns,
5954 this strategy can not be used if any of the columns in the
5955 materialized table will be BLOB/GEOMETRY columns. (Note that
5956 also columns for non-BLOB values that may be greater in size
5957 than CONVERT_IF_BIGGER_TO_BLOB, will be represented as BLOB
5958 columns.)
5959
5960 2. Materialize and then do a full scan of the materialized table.
5961 The same criteria as for MaterializeLookup are applied, except that
5962 BLOB/GEOMETRY columns are allowed.
5963 */
5964
5965 9374 static void semijoin_types_allow_materialization(TABLE_LIST *sj_nest) {
5966
1/2
✓ Branch 0 taken 9374 times.
✗ Branch 1 not taken.
9374 DBUG_TRACE;
5967
5968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9374 times.
9374 assert(sj_nest->nested_join->sj_outer_exprs.size() ==
5969 sj_nest->nested_join->sj_inner_exprs.size());
5970
5971
5/6
✓ Branch 0 taken 9374 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 9372 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 9372 times.
18748 if (sj_nest->nested_join->sj_outer_exprs.size() > MAX_REF_PARTS ||
5972 9374 sj_nest->nested_join->sj_outer_exprs.size() == 0) {
5973 // building an index is impossible
5974 2 sj_nest->nested_join->sjm.scan_allowed = false;
5975 2 sj_nest->nested_join->sjm.lookup_allowed = false;
5976 2 return;
5977 }
5978
5979 9372 sj_nest->nested_join->sjm.scan_allowed = true;
5980 9372 sj_nest->nested_join->sjm.lookup_allowed = true;
5981
5982 9372 bool blobs_involved = false;
5983 9372 uint total_lookup_index_length = 0;
5984 uint max_key_length, max_key_part_length, max_key_parts;
5985 /*
5986 Maximum lengths for keys and key parts that are supported by
5987 the temporary table storage engine(s).
5988 */
5989
1/2
✓ Branch 0 taken 9372 times.
✗ Branch 1 not taken.
9372 get_max_key_and_part_length(&max_key_length, &max_key_part_length,
5990 &max_key_parts);
5991
1/2
✓ Branch 0 taken 9372 times.
✗ Branch 1 not taken.
9372 auto it1 = sj_nest->nested_join->sj_outer_exprs.begin();
5992
1/2
✓ Branch 0 taken 9372 times.
✗ Branch 1 not taken.
9372 auto it2 = sj_nest->nested_join->sj_inner_exprs.begin();
5993
4/6
✓ Branch 0 taken 18886 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18886 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10202 times.
✓ Branch 5 taken 8684 times.
29088 while (it1 != sj_nest->nested_join->sj_outer_exprs.end() &&
5994
5/8
✓ Branch 0 taken 10202 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10202 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10202 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10202 times.
✓ Branch 7 taken 8684 times.
29088 it2 != sj_nest->nested_join->sj_inner_exprs.end()) {
5995
2/4
✓ Branch 0 taken 10202 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10202 times.
✗ Branch 3 not taken.
10202 Item *outer = *it1++;
5996
2/4
✓ Branch 0 taken 10202 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10202 times.
✗ Branch 3 not taken.
10202 Item *inner = *it2++;
5997
4/8
✓ Branch 0 taken 10202 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10202 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10202 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10202 times.
✗ Branch 7 not taken.
10202 assert(outer->real_item() && inner->real_item());
5998
3/4
✓ Branch 0 taken 10202 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 688 times.
✓ Branch 3 taken 9514 times.
10202 if (!types_allow_materialization(outer, inner)) {
5999 688 sj_nest->nested_join->sjm.scan_allowed = false;
6000 688 sj_nest->nested_join->sjm.lookup_allowed = false;
6001 688 return;
6002 }
6003
1/2
✓ Branch 0 taken 9514 times.
✗ Branch 1 not taken.
9514 blobs_involved |= inner->is_blob_field();
6004
6005 // Calculate the index length of materialized table
6006
1/2
✓ Branch 0 taken 9514 times.
✗ Branch 1 not taken.
9514 const uint lookup_index_length = get_key_length_tmp_table(inner);
6007
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9512 times.
9514 if (lookup_index_length > max_key_part_length)
6008 2 sj_nest->nested_join->sjm.lookup_allowed = false;
6009 9514 total_lookup_index_length += lookup_index_length;
6010 }
6011
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8682 times.
8684 if (total_lookup_index_length > max_key_length)
6012 2 sj_nest->nested_join->sjm.lookup_allowed = false;
6013
6014
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 8412 times.
8684 if (blobs_involved) sj_nest->nested_join->sjm.lookup_allowed = false;
6015
6016
3/8
✓ Branch 0 taken 8684 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8684 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8684 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
8684 DBUG_PRINT("info", ("semijoin_types_allow_materialization: ok, allowed"));
6017
2/2
✓ Branch 0 taken 8684 times.
✓ Branch 1 taken 690 times.
9374 }
6018
6019 /**
6020 Index dive can be skipped if the following conditions are satisfied:
6021 F1) For a single table query:
6022 a) FORCE INDEX applies to a single index.
6023 b) No subquery is present.
6024 c) Fulltext Index is not involved.
6025 d) No GROUP-BY or DISTINCT clause.
6026 e) No ORDER-BY clause.
6027
6028 F2) Not applicable to multi-table query.
6029
6030 F3) This optimization is not applicable to EXPLAIN queries.
6031
6032 @param tab JOIN_TAB object.
6033 @param thd THD object.
6034 */
6035 501115 static bool check_skip_records_in_range_qualification(JOIN_TAB *tab, THD *thd) {
6036 501115 Query_block *select = thd->lex->current_query_block();
6037 501115 TABLE *table = tab->table();
6038
2/2
✓ Branch 0 taken 1578 times.
✓ Branch 1 taken 64 times.
1642 return ((table->force_index &&
6039
2/2
✓ Branch 0 taken 1545 times.
✓ Branch 1 taken 33 times.
3220 table->keys_in_use_for_query.bits_set() == 1) && // F1.a
6040 1578 select->parent_lex->is_single_level_stmt() && // F1.b
6041
2/2
✓ Branch 0 taken 1544 times.
✓ Branch 1 taken 1 times.
1545 !select->has_ft_funcs() && // F1.c
6042
4/4
✓ Branch 0 taken 1462 times.
✓ Branch 1 taken 82 times.
✓ Branch 2 taken 1456 times.
✓ Branch 3 taken 6 times.
1544 (!select->is_grouped() && !select->is_distinct()) && // F1.d
6043
4/4
✓ Branch 0 taken 1306 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 1272 times.
✓ Branch 3 taken 34 times.
2762 !select->is_ordered() && // F1.e
6044
2/2
✓ Branch 0 taken 1642 times.
✓ Branch 1 taken 499473 times.
504063 select->join_list->size() == 1 && // F2
6045
2/2
✓ Branch 0 taken 1192 times.
✓ Branch 1 taken 80 times.
502387 !thd->lex->is_explain()); // F3
6046 }
6047
6048 /*****************************************************************************
6049 Create JOIN_TABS, make a guess about the table types,
6050 Approximate how many records will be used in each table
6051 *****************************************************************************/
6052
6053 /**
6054 Returns estimated number of rows that could be fetched by given
6055 access method.
6056
6057 The function calls the range optimizer to estimate the cost of the
6058 cheapest QUICK_* index access method to scan one or several of the
6059 'keys' using the conditions 'select->cond'. The range optimizer
6060 compares several different types of 'quick select' methods (range
6061 scan, index merge, loose index scan) and selects the cheapest one.
6062
6063 If the best index access method is cheaper than a table- and an index
6064 scan, then the range optimizer also constructs the corresponding
6065 QUICK_* object and assigns it to select->quick. In most cases this
6066 is the QUICK_* object used at later (optimization and execution)
6067 phases.
6068
6069 @param thd Session that runs the query.
6070 @param tab JOIN_TAB of source table.
6071 @param limit maximum number of rows to select.
6072
6073 @note
6074 In case of valid range, a RowIterator object will be constructed and
6075 saved in select->quick.
6076
6077 @return Estimated number of result rows selected from 'tab'.
6078
6079 @retval HA_POS_ERROR For derived tables/views or if an error occur.
6080 @retval 0 If impossible query (i.e. certainly no rows will be
6081 selected.)
6082 */
6083 501115 static ha_rows get_quick_record_count(THD *thd, JOIN_TAB *tab, ha_rows limit) {
6084
1/2
✓ Branch 0 taken 501115 times.
✗ Branch 1 not taken.
501115 DBUG_TRACE;
6085 uchar buff[STACK_BUFF_ALLOC];
6086
2/4
✓ Branch 0 taken 501115 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 501115 times.
501115 if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
6087 return 0; // Fatal error flag is set
6088 501115 TABLE_LIST *const tl = tab->table_ref;
6089 1002230 tab->set_skip_records_in_range(
6090
1/2
✓ Branch 0 taken 501115 times.
✗ Branch 1 not taken.
501115 check_skip_records_in_range_qualification(tab, thd));
6091
6092 // Derived tables aren't filled yet, so no stats are available.
6093
2/2
✓ Branch 0 taken 500738 times.
✓ Branch 1 taken 377 times.
501115 if (!tl->uses_materialization()) {
6094 AccessPath *range_scan;
6095 500738 Key_map keys_to_use = tab->const_keys;
6096 500738 keys_to_use.merge(tab->skip_scan_keys);
6097 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
6098 500738 thd->variables.range_alloc_block_size);
6099
3/4
✓ Branch 0 taken 84617 times.
✓ Branch 1 taken 416121 times.
✓ Branch 2 taken 500738 times.
✗ Branch 3 not taken.
1417597 int error = test_quick_select(
6100 thd, thd->mem_root, &temp_mem_root, keys_to_use, 0,
6101 0, // empty table_map
6102 limit,
6103 false, // don't force quick range
6104 500738 ORDER_NOT_RELEVANT, tab->table(), tab->skip_records_in_range(),
6105 500738 tab->join_cond() ? tab->join_cond() : tab->join()->where_cond,
6106 500738 &tab->needed_reg, tab->table()->force_index, tab->join()->query_block,
6107 &range_scan);
6108 500738 tab->set_range_scan(range_scan);
6109
6110
2/2
✓ Branch 0 taken 133506 times.
✓ Branch 1 taken 367232 times.
500738 if (error == 1) return range_scan->num_output_rows;
6111
2/2
✓ Branch 0 taken 10018 times.
✓ Branch 1 taken 357214 times.
367232 if (error == -1) {
6112 10018 tl->table->reginfo.impossible_range = true;
6113 10018 return 0;
6114 }
6115
5/8
✓ Branch 0 taken 357214 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 357214 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 357209 times.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
357214 DBUG_PRINT("warning", ("Couldn't use record count on const keypart"));
6116
8/10
✓ Branch 0 taken 357214 times.
✓ Branch 1 taken 143524 times.
✓ Branch 2 taken 362 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 362 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 362 times.
✓ Branch 8 taken 15 times.
✓ Branch 9 taken 362 times.
501115 } else if (tl->is_table_function() || tl->materializable_is_const()) {
6117
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 tl->fetch_number_of_rows();
6118 15 return tl->table->file->stats.records;
6119 }
6120 357576 return HA_POS_ERROR;
6121 501115 }
6122
6123 /*
6124 Get estimated record length for semi-join materialization temptable
6125
6126 SYNOPSIS
6127 get_tmp_table_rec_length()
6128 items IN subquery's select list.
6129
6130 DESCRIPTION
6131 Calculate estimated record length for semi-join materialization
6132 temptable. It's an estimate because we don't follow every bit of
6133 create_tmp_table()'s logic. This isn't necessary as the return value of
6134 this function is used only for cost calculations.
6135
6136 RETURN
6137 Length of the temptable record, in bytes
6138 */
6139
6140 11033 static uint get_tmp_table_rec_length(const mem_root_deque<Item *> &items) {
6141 11033 uint len = 0;
6142
8/14
✓ Branch 0 taken 11033 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11033 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11033 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12040 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 12040 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 23073 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 12040 times.
✓ Branch 13 taken 11033 times.
23073 for (Item *item : VisibleFields(items)) {
6143
5/7
✓ Branch 0 taken 12040 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 264 times.
✓ Branch 3 taken 8496 times.
✓ Branch 4 taken 3144 times.
✓ Branch 5 taken 136 times.
✗ Branch 6 not taken.
12040 switch (item->result_type()) {
6144 264 case REAL_RESULT:
6145 264 len += sizeof(double);
6146 264 break;
6147 8496 case INT_RESULT:
6148
2/2
✓ Branch 0 taken 8191 times.
✓ Branch 1 taken 305 times.
8496 if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
6149 8191 len += 8;
6150 else
6151 305 len += 4;
6152 8496 break;
6153 3144 case STRING_RESULT:
6154 /* DATE/TIME and GEOMETRY fields have STRING_RESULT result type. */
6155
6/6
✓ Branch 0 taken 2986 times.
✓ Branch 1 taken 158 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 2974 times.
✓ Branch 4 taken 170 times.
✓ Branch 5 taken 2974 times.
3144 if (item->is_temporal() || item->data_type() == MYSQL_TYPE_GEOMETRY)
6156 170 len += 8;
6157 else
6158 2974 len += item->max_length;
6159 3144 break;
6160 136 case DECIMAL_RESULT:
6161 136 len += 10;
6162 136 break;
6163 case ROW_RESULT:
6164 default:
6165 assert(0); /* purecov: deadcode */
6166 break;
6167 }
6168 }
6169 11033 return len;
6170 }
6171
6172 /**
6173 Writes to the optimizer trace information about dependencies between
6174 tables.
6175 @param trace optimizer trace
6176 @param join_tabs all JOIN_TABs of the join
6177 @param table_count how many JOIN_TABs in the 'join_tabs' array
6178 */
6179 2711 static void trace_table_dependencies(Opt_trace_context *trace,
6180 JOIN_TAB *join_tabs, uint table_count) {
6181
1/2
✓ Branch 0 taken 2711 times.
✗ Branch 1 not taken.
2711 Opt_trace_object trace_wrapper(trace);
6182
1/2
✓ Branch 0 taken 2711 times.
✗ Branch 1 not taken.
2711 Opt_trace_array trace_dep(trace, "table_dependencies");
6183
2/2
✓ Branch 0 taken 3207 times.
✓ Branch 1 taken 2711 times.
5918 for (uint i = 0; i < table_count; i++) {
6184 3207 TABLE_LIST *table_ref = join_tabs[i].table_ref;
6185
1/2
✓ Branch 0 taken 3207 times.
✗ Branch 1 not taken.
3207 Opt_trace_object trace_one_table(trace);
6186
2/4
✓ Branch 0 taken 3207 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3207 times.
✗ Branch 3 not taken.
6414 trace_one_table.add_utf8_table(table_ref).add(
6187 3207 "row_may_be_null", table_ref->table->is_nullable());
6188 3207 const table_map map = table_ref->map();
6189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3207 times.
3207 assert(map < (1ULL << table_count));
6190
1/2
✓ Branch 0 taken 3966 times.
✗ Branch 1 not taken.
3966 for (uint j = 0; j < table_count; j++) {
6191
2/2
✓ Branch 0 taken 3207 times.
✓ Branch 1 taken 759 times.
3966 if (map & (1ULL << j)) {
6192
1/2
✓ Branch 0 taken 3207 times.
✗ Branch 1 not taken.
3207 trace_one_table.add("map_bit", j);
6193 3207 break;
6194 }
6195 }
6196
1/2
✓ Branch 0 taken 3207 times.
✗ Branch 1 not taken.
3207 Opt_trace_array depends_on(trace, "depends_on_map_bits");
6197 static_assert(sizeof(table_ref->map()) <= 64,
6198 "RAND_TABLE_BIT may be in join_tabs[i].dependent, so we test "
6199 "all 64 bits.");
6200
2/2
✓ Branch 0 taken 205248 times.
✓ Branch 1 taken 3207 times.
208455 for (uint j = 0; j < 64; j++) {
6201
3/4
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 204948 times.
✓ Branch 2 taken 300 times.
✗ Branch 3 not taken.
205248 if (join_tabs[i].dependent & (1ULL << j)) depends_on.add(j);
6202 }
6203 3207 }
6204 2711 }
6205
6206 /**
6207 Add to join_tab[i]->condition() "table.field IS NOT NULL" conditions
6208 we've inferred from ref/eq_ref access performed.
6209
6210 This function is a part of "Early NULL-values filtering for ref access"
6211 optimization.
6212
6213 Example of this optimization:
6214 For query SELECT * FROM t1,t2 WHERE t2.key=t1.field @n
6215 and plan " any-access(t1), ref(t2.key=t1.field) " @n
6216 add "t1.field IS NOT NULL" to t1's table condition. @n
6217
6218 Description of the optimization:
6219
6220 We look through equalities chosen to perform ref/eq_ref access,
6221 pick equalities that have form "tbl.part_of_key = othertbl.field"
6222 (where othertbl is a non-const table and othertbl.field may be NULL)
6223 and add them to conditions on corresponding tables (othertbl in this
6224 example).
6225
6226 Exception from that is the case when referred_tab->join != join.
6227 I.e. don't add NOT NULL constraints from any embedded subquery.
6228 Consider this query:
6229 @code
6230 SELECT A.f2 FROM t1 LEFT JOIN t2 A ON A.f2 = f1
6231 WHERE A.f3=(SELECT MIN(f3) FROM t2 C WHERE A.f4 = C.f4) OR A.f3 IS NULL;
6232 @endcode
6233 Here condition A.f3 IS NOT NULL is going to be added to the WHERE
6234 condition of the embedding query.
6235 Another example:
6236 SELECT * FROM t10, t11 WHERE (t10.a < 10 OR t10.a IS NULL)
6237 AND t11.b <=> t10.b AND (t11.a = (SELECT MAX(a) FROM t12
6238 WHERE t12.b = t10.a ));
6239 Here condition t10.a IS NOT NULL is going to be added.
6240 In both cases addition of NOT NULL condition will erroneously reject
6241 some rows of the result set.
6242 referred_tab->join != join constraint would disallow such additions.
6243
6244 This optimization doesn't affect the choices that ref, range, or join
6245 optimizer make. This was intentional because this was added after 4.1
6246 was GA.
6247
6248 Implementation overview
6249 1. update_ref_and_keys() accumulates info about null-rejecting
6250 predicates in in Key_field::null_rejecting
6251 1.1 add_key_part saves these to Key_use.
6252 2. create_ref_for_key copies them to TABLE_REF.
6253 3. add_not_null_conds adds "x IS NOT NULL" to join_tab->m_condition of
6254 appropriate JOIN_TAB members.
6255
6256 @returns false on success, true on error
6257 */
6258
6259 1816536 static bool add_not_null_conds(JOIN *join) {
6260
1/2
✓ Branch 0 taken 1816640 times.
✗ Branch 1 not taken.
1816536 DBUG_TRACE;
6261
3/6
✓ Branch 0 taken 1816640 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1816640 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1816640 times.
✗ Branch 5 not taken.
1816640 ASSERT_BEST_REF_IN_JOIN_ORDER(join);
6262
2/2
✓ Branch 0 taken 6167481 times.
✓ Branch 1 taken 1816728 times.
7984209 for (uint i = join->const_tables; i < join->tables; i++) {
6263 6167481 JOIN_TAB *const tab = join->best_ref[i];
6264
4/4
✓ Branch 0 taken 4234832 times.
✓ Branch 1 taken 1567356 times.
✓ Branch 2 taken 484 times.
✓ Branch 3 taken 4234347 times.
16204485 if ((tab->type() != JT_REF && tab->type() != JT_EQ_REF &&
6265
6/6
✓ Branch 0 taken 5802173 times.
✓ Branch 1 taken 365384 times.
✓ Branch 2 taken 516771 times.
✓ Branch 3 taken 1416470 times.
✓ Branch 4 taken 4751122 times.
✓ Branch 5 taken 1416466 times.
16569977 tab->type() != JT_REF_OR_NULL) ||
6266 1933224 tab->table()->is_nullable()) {
6267 4751122 continue;
6268 }
6269
2/2
✓ Branch 0 taken 1691132 times.
✓ Branch 1 taken 1416447 times.
3107593 for (uint keypart = 0; keypart < tab->ref().key_parts; keypart++) {
6270
2/2
✓ Branch 0 taken 1525540 times.
✓ Branch 1 taken 165577 times.
1691132 if ((tab->ref().null_rejecting & ((key_part_map)1 << keypart)) == 0) {
6271 1561983 continue;
6272 }
6273
1/2
✓ Branch 0 taken 165587 times.
✗ Branch 1 not taken.
165577 Item *const item = tab->ref().items[keypart]->real_item();
6274
7/8
✓ Branch 0 taken 165587 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 140235 times.
✓ Branch 3 taken 25352 times.
✓ Branch 4 taken 812 times.
✓ Branch 5 taken 139423 times.
✓ Branch 6 taken 26164 times.
✓ Branch 7 taken 139423 times.
165587 if (item->type() != Item::FIELD_ITEM || !item->is_nullable()) continue;
6275 139423 Item_field *const not_null_item = down_cast<Item_field *>(item);
6276 139423 JOIN_TAB *referred_tab = not_null_item->field->table->reginfo.join_tab;
6277 /*
6278 For UPDATE queries such as:
6279 UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
6280 not_null_item is the t1.f1, but it's referred_tab is 0.
6281 */
6282
5/6
✓ Branch 0 taken 139096 times.
✓ Branch 1 taken 327 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 139096 times.
✓ Branch 4 taken 327 times.
✓ Branch 5 taken 139096 times.
139423 if (referred_tab == nullptr || referred_tab->join() != join) continue;
6283 /* Skip if we already have a 'not null' predicate for 'item' */
6284
3/4
✓ Branch 0 taken 139096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9952 times.
✓ Branch 3 taken 129144 times.
139096 if (has_not_null_predicate(referred_tab->condition(), not_null_item))
6285 9952 continue;
6286
2/4
✓ Branch 0 taken 129144 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 129144 times.
✗ Branch 3 not taken.
129144 Item *notnull = new Item_func_isnotnull(not_null_item);
6287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 129144 times.
129144 if (notnull == nullptr) return true;
6288 /*
6289 We need to do full fix_fields() call here in order to have correct
6290 notnull->const_item(). This is needed e.g. by test_quick_select
6291 when it is called from make_join_query_block after this function is
6292 called.
6293 */
6294
2/4
✓ Branch 0 taken 129144 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 129144 times.
129144 if (notnull->fix_fields(join->thd, &notnull)) return true;
6295
2/6
✓ Branch 0 taken 129144 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 129144 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
129144 DBUG_EXECUTE("where",
6296 print_where(join->thd, notnull, referred_tab->table()->alias,
6297 QT_ORDINARY););
6298
1/2
✓ Branch 0 taken 129144 times.
✗ Branch 1 not taken.
129144 referred_tab->and_with_condition(notnull);
6299 }
6300 }
6301 1816728 return false;
6302 1816728 }
6303
6304 /**
6305 Check all existing AND'ed predicates in 'cond' for an existing
6306 'is not null 'not_null_item''-predicate.
6307
6308 A condition consisting of multiple AND'ed terms is recursively
6309 decomposed in the search for the specified not null predicate.
6310
6311 @param cond Condition to be checked.
6312 @param not_null_item The item in: 'is not null 'item'' to search for
6313
6314 @return true if 'is not null 'not_null_item'' is a predicate
6315 in the specified 'cond'.
6316 */
6317 139492 static bool has_not_null_predicate(Item *cond, Item_field *not_null_item) {
6318
2/2
✓ Branch 0 taken 101073 times.
✓ Branch 1 taken 38419 times.
139492 if (cond == nullptr) return false;
6319
2/2
✓ Branch 0 taken 38214 times.
✓ Branch 1 taken 205 times.
38419 if (cond->type() == Item::FUNC_ITEM) {
6320 38214 Item_func *item_func = down_cast<Item_func *>(cond);
6321 38214 const Item_func::Functype func_type = item_func->functype();
6322
1/2
✓ Branch 0 taken 38214 times.
✗ Branch 1 not taken.
76428 return (func_type == Item_func::ISNOTNULL_FUNC &&
6323
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 28262 times.
76428 item_func->key_item() == not_null_item);
6324
1/2
✓ Branch 0 taken 205 times.
✗ Branch 1 not taken.
205 } else if (cond->type() == Item::COND_ITEM) {
6325 205 Item_cond *item_cond = down_cast<Item_cond *>(cond);
6326
1/2
✓ Branch 0 taken 205 times.
✗ Branch 1 not taken.
205 if (item_cond->functype() == Item_func::COND_AND_FUNC) {
6327
1/2
✓ Branch 0 taken 205 times.
✗ Branch 1 not taken.
205 List_iterator<Item> li(*item_cond->argument_list());
6328 Item *item;
6329
2/2
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 183 times.
579 while ((item = li++)) {
6330
3/4
✓ Branch 0 taken 396 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 374 times.
396 if (has_not_null_predicate(item, not_null_item)) return true;
6331 }
6332 }
6333 }
6334 183 return false;
6335 }
6336
6337 /**
6338 Check if given expression only uses fields covered by index @a keyno in the
6339 table tbl. The expression can use any fields in any other tables.
6340
6341 The expression is guaranteed not to be AND or OR - those constructs are
6342 handled outside of this function.
6343
6344 Restrict some function types from being pushed down to storage engine:
6345 a) Don't push down the triggered conditions. Nested outer joins execution
6346 code may need to evaluate a condition several times (both triggered and
6347 untriggered).
6348 TODO: Consider cloning the triggered condition and using the copies for:
6349 1. push the first copy down, to have most restrictive index condition
6350 possible.
6351 2. Put the second copy into tab->m_condition.
6352 b) Stored functions contain a statement that might start new operations (like
6353 DML statements) from within the storage engine. This does not work against
6354 all SEs.
6355 c) Subqueries might contain nested subqueries and involve more tables.
6356 TODO: ROY: CHECK THIS
6357 d) Do not push down internal functions of type DD_INTERNAL_FUNC. When ICP is
6358 enabled, pushing internal functions to storage engine for evaluation will
6359 open data-dictionary tables. In InnoDB storage engine this will result in
6360 situation like recursive latching of same page by the same thread. To avoid
6361 such situation, internal functions of type DD_INTERNAL_FUNC are not pushed
6362 to storage engine for evaluation.
6363
6364 @param item Expression to check
6365 @param tbl The table having the index
6366 @param keyno The index number
6367 @param other_tbls_ok true <=> Fields of other non-const tables are allowed
6368
6369 @return false if No, true if Yes
6370 */
6371
6372 20483 bool uses_index_fields_only(Item *item, TABLE *tbl, uint keyno,
6373 bool other_tbls_ok) {
6374 // Restrictions b and c.
6375
6/6
✓ Branch 0 taken 20471 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 152 times.
✓ Branch 3 taken 20319 times.
✓ Branch 4 taken 164 times.
✓ Branch 5 taken 20319 times.
20483 if (item->has_stored_program() || item->has_subquery()) return false;
6376
6377 // No table fields in const items
6378
2/2
✓ Branch 0 taken 4704 times.
✓ Branch 1 taken 15615 times.
20319 if (item->const_for_execution()) return true;
6379
6380 15615 const Item::Type item_type = item->type();
6381
6382
4/5
✓ Branch 0 taken 7864 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7638 times.
✓ Branch 3 taken 79 times.
✓ Branch 4 taken 34 times.
15615 switch (item_type) {
6383 7864 case Item::FUNC_ITEM: {
6384 7864 Item_func *item_func = (Item_func *)item;
6385 7864 const Item_func::Functype func_type = item_func->functype();
6386
6387
3/4
✓ Branch 0 taken 7650 times.
✓ Branch 1 taken 214 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7650 times.
7864 if (func_type == Item_func::TRIG_COND_FUNC || // Restriction a.
6388 func_type == Item_func::DD_INTERNAL_FUNC) // Restriction d.
6389 214 return false;
6390
6391 /* This is a function, apply condition recursively to arguments */
6392
2/2
✓ Branch 0 taken 7644 times.
✓ Branch 1 taken 6 times.
7650 if (item_func->argument_count() > 0) {
6393 Item **item_end =
6394 7644 (item_func->arguments()) + item_func->argument_count();
6395
2/2
✓ Branch 0 taken 12601 times.
✓ Branch 1 taken 4641 times.
17242 for (Item **child = item_func->arguments(); child != item_end;
6396 child++) {
6397
2/2
✓ Branch 0 taken 3003 times.
✓ Branch 1 taken 9598 times.
12601 if (!uses_index_fields_only(*child, tbl, keyno, other_tbls_ok))
6398 3003 return false;
6399 }
6400 }
6401 4647 return true;
6402 }
6403 case Item::COND_ITEM: {
6404 /*
6405 This is a AND/OR condition. Regular AND/OR clauses are handled by
6406 make_cond_for_index() which will chop off the part that can be
6407 checked with index. This code is for handling non-top-level AND/ORs,
6408 e.g. func(x AND y).
6409 */
6410 List_iterator<Item> li(*((Item_cond *)item)->argument_list());
6411 Item *cond_item;
6412 while ((cond_item = li++)) {
6413 if (!uses_index_fields_only(cond_item, tbl, keyno, other_tbls_ok))
6414 return false;
6415 }
6416 return true;
6417 }
6418 7638 case Item::FIELD_ITEM: {
6419 7638 const Item_field *item_field = down_cast<const Item_field *>(item);
6420
2/2
✓ Branch 0 taken 236 times.
✓ Branch 1 taken 7402 times.
7638 if (item_field->field->table != tbl) return other_tbls_ok;
6421 /*
6422 The below is probably a repetition - the first part checks the
6423 other two, but let's play it safe:
6424 */
6425 7402 return item_field->field->part_of_key.is_set(keyno) &&
6426
3/4
✓ Branch 0 taken 4494 times.
✓ Branch 1 taken 2908 times.
✓ Branch 2 taken 4494 times.
✗ Branch 3 not taken.
11896 item_field->field->type() != MYSQL_TYPE_GEOMETRY &&
6427
1/2
✓ Branch 0 taken 4494 times.
✗ Branch 1 not taken.
11896 item_field->field->type() != MYSQL_TYPE_BLOB;
6428 }
6429 79 case Item::REF_ITEM:
6430 79 return uses_index_fields_only(item->real_item(), tbl, keyno,
6431 79 other_tbls_ok);
6432 34 default:
6433 34 return false; /* Play it safe, don't push unknown non-const items */
6434 }
6435 }
6436
6437 /**
6438 Optimize semi-join nests that could be run with sj-materialization
6439
6440 @param join The join to optimize semi-join nests for
6441
6442 @details
6443 Optimize each of the semi-join nests that can be run with
6444 materialization. For each of the nests, we
6445 - Generate the best join order for this "sub-join" and remember it;
6446 - Remember the sub-join execution cost (it's part of materialization
6447 cost);
6448 - Calculate other costs that will be incurred if we decide
6449 to use materialization strategy for this semi-join nest.
6450
6451 All obtained information is saved and will be used by the main join
6452 optimization pass.
6453
6454 @return false if successful, true if error
6455 */
6456
6457 21301 static bool optimize_semijoin_nests_for_materialization(JOIN *join) {
6458
1/2
✓ Branch 0 taken 21301 times.
✗ Branch 1 not taken.
21301 DBUG_TRACE;
6459 21301 Opt_trace_context *const trace = &join->thd->opt_trace;
6460
6461
7/12
✓ Branch 0 taken 21301 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21301 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19904 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 19904 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 41205 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 19904 times.
✓ Branch 11 taken 21301 times.
41205 for (TABLE_LIST *sj_nest : join->query_block->sj_nests) {
6462 /* As a precaution, reset pointers that were used in prior execution */
6463 19904 sj_nest->nested_join->sjm.positions = nullptr;
6464
6465 /* Calculate the cost of materialization if materialization is allowed. */
6466
2/2
✓ Branch 0 taken 10138 times.
✓ Branch 1 taken 9766 times.
19904 if (sj_nest->nested_join->sj_enabled_strategies &
6467 OPTIMIZER_SWITCH_MATERIALIZATION) {
6468 /* A semi-join nest should not contain tables marked as const */
6469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10138 times.
10138 assert(!(sj_nest->sj_inner_tables & join->const_table_map));
6470
6471
1/2
✓ Branch 0 taken 10138 times.
✗ Branch 1 not taken.
10138 Opt_trace_object trace_wrapper(trace);
6472 Opt_trace_object trace_sjmat(
6473
1/2
✓ Branch 0 taken 10138 times.
✗ Branch 1 not taken.
10138 trace, "execution_plan_for_potential_materialization");
6474
1/2
✓ Branch 0 taken 10138 times.
✗ Branch 1 not taken.
10138 Opt_trace_array trace_sjmat_steps(trace, "steps");
6475 /*
6476 Try semijoin materialization if the semijoin is classified as
6477 non-trivially-correlated.
6478 */
6479
2/2
✓ Branch 0 taken 764 times.
✓ Branch 1 taken 9374 times.
10138 if (sj_nest->nested_join->sj_corr_tables) continue;
6480 /*
6481 Check whether data types allow execution with materialization.
6482 */
6483
1/2
✓ Branch 0 taken 9374 times.
✗ Branch 1 not taken.
9374 semijoin_types_allow_materialization(sj_nest);
6484
6485
2/2
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 8684 times.
9374 if (!sj_nest->nested_join->sjm.scan_allowed &&
6486
1/2
✓ Branch 0 taken 690 times.
✗ Branch 1 not taken.
690 !sj_nest->nested_join->sjm.lookup_allowed)
6487 690 continue;
6488
6489
3/6
✓ Branch 0 taken 8684 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8684 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8684 times.
8684 if (Optimize_table_order(join->thd, join, sj_nest).choose_table_order())
6490 return true;
6491 8684 const uint n_tables = my_count_bits(sj_nest->sj_inner_tables);
6492 8684 calculate_materialization_costs(join, sj_nest, n_tables,
6493
1/2
✓ Branch 0 taken 8684 times.
✗ Branch 1 not taken.
8684 &sj_nest->nested_join->sjm);
6494 /*
6495 Cost data is in sj_nest->nested_join->sjm. We also need to save the
6496 plan:
6497 */
6498 17368 if (!(sj_nest->nested_join->sjm.positions =
6499
2/4
✓ Branch 0 taken 8684 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8684 times.
8684 (POSITION *)join->thd->alloc(sizeof(POSITION) * n_tables)))
6500 return true;
6501 8684 memcpy(sj_nest->nested_join->sjm.positions,
6502 8684 join->best_positions + join->const_tables,
6503 8684 sizeof(POSITION) * n_tables);
6504
6/9
✓ Branch 0 taken 8684 times.
✓ Branch 1 taken 1454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8684 times.
✓ Branch 4 taken 1454 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8684 times.
✓ Branch 7 taken 1454 times.
✗ Branch 8 not taken.
13046 }
6505 }
6506 21301 return false;
6507 21301 }
6508
6509 /*
6510 Check if table's Key_use elements have an eq_ref(outer_tables) candidate
6511
6512 SYNOPSIS
6513 find_eq_ref_candidate()
6514 tl Table to be checked
6515 sj_inner_tables Bitmap of inner tables. eq_ref(inner_table) doesn't
6516 count.
6517
6518 DESCRIPTION
6519 Check if table's Key_use elements have an eq_ref(outer_tables) candidate
6520
6521 TODO
6522 Check again if it is feasible to factor common parts with constant table
6523 search
6524
6525 RETURN
6526 true - There exists an eq_ref(outer-tables) candidate
6527 false - Otherwise
6528 */
6529
6530 30020 static bool find_eq_ref_candidate(TABLE_LIST *tl, table_map sj_inner_tables) {
6531 30020 Key_use *keyuse = tl->table->reginfo.join_tab->keyuse();
6532
6533
2/2
✓ Branch 0 taken 9187 times.
✓ Branch 1 taken 20833 times.
30020 if (keyuse) {
6534 while (true) /* For each key */
6535 {
6536 11132 const uint key = keyuse->key;
6537 11132 KEY *const keyinfo = tl->table->key_info + key;
6538 11132 key_part_map bound_parts = 0;
6539
2/2
✓ Branch 0 taken 7682 times.
✓ Branch 1 taken 3450 times.
11132 if ((keyinfo->flags & (HA_NOSAME)) == HA_NOSAME) {
6540 do /* For all equalities on all key parts */
6541 {
6542 /* Check if this is "t.keypart = expr(outer_tables) */
6543
2/2
✓ Branch 0 taken 4309 times.
✓ Branch 1 taken 5338 times.
9647 if (!(keyuse->used_tables & sj_inner_tables) &&
6544
1/2
✓ Branch 0 taken 4309 times.
✗ Branch 1 not taken.
4309 !(keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)) {
6545 /*
6546 Consider only if the resulting condition does not pass a NULL
6547 value through. Especially needed for a UNIQUE index on NULLable
6548 columns where a duplicate row is possible with NULL values.
6549 */
6550
5/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4307 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4307 times.
✓ Branch 5 taken 2 times.
4311 if (keyuse->null_rejecting || !keyuse->val->is_nullable() ||
6551
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 !keyinfo->key_part[keyuse->keypart].field->is_nullable())
6552 4307 bound_parts |= (key_part_map)1 << keyuse->keypart;
6553 }
6554 9647 keyuse++;
6555
4/4
✓ Branch 0 taken 5135 times.
✓ Branch 1 taken 4512 times.
✓ Branch 2 taken 1965 times.
✓ Branch 3 taken 3170 times.
9647 } while (keyuse->key == key && keyuse->table_ref == tl);
6556
6557
2/2
✓ Branch 0 taken 3037 times.
✓ Branch 1 taken 4645 times.
7682 if (bound_parts == LOWER_BITS(uint, keyinfo->user_defined_key_parts))
6558 3037 return true;
6559
2/2
✓ Branch 0 taken 3023 times.
✓ Branch 1 taken 1622 times.
4645 if (keyuse->table_ref != tl) return false;
6560 } else {
6561 do {
6562 4694 keyuse++;
6563
2/2
✓ Branch 0 taken 3127 times.
✓ Branch 1 taken 1567 times.
4694 if (keyuse->table_ref != tl) return false;
6564
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 323 times.
1567 } while (keyuse->key == key);
6565 }
6566 1945 }
6567 }
6568 20833 return false;
6569 }
6570
6571 /**
6572 Pull tables out of semi-join nests based on functional dependencies
6573
6574 @param join The join where to do the semi-join table pullout
6575
6576 @return False if successful, true if error (Out of memory)
6577
6578 @details
6579 Pull tables out of semi-join nests based on functional dependencies,
6580 ie. if a table is accessed via eq_ref(outer_tables).
6581 The function may be called several times, the caller is responsible
6582 for setting up proper key information that this function acts upon.
6583
6584 PRECONDITIONS
6585 When this function is called, the join may have several semi-join nests
6586 but it is guaranteed that one semi-join nest does not contain another.
6587 For functionally dependent tables to be pulled out, key information must
6588 have been calculated (see update_ref_and_keys()).
6589
6590 POSTCONDITIONS
6591 * Tables that were pulled out are removed from the semi-join nest they
6592 belonged to and added to the parent join nest.
6593 * For these tables, the used_tables and not_null_tables fields of
6594 the semi-join nest they belonged to will be adjusted.
6595 The semi-join nest is also marked as correlated, and
6596 sj_corr_tables and sj_depends_on are adjusted if necessary.
6597 * Semi-join nests' sj_inner_tables is set equal to used_tables
6598
6599 NOTE
6600 Table pullout may make uncorrelated subquery correlated. Consider this
6601 example:
6602
6603 ... WHERE oe IN (SELECT it1.primary_key WHERE p(it1, it2) ... )
6604
6605 here table it1 can be pulled out (we have it1.primary_key=oe which gives
6606 us functional dependency). Once it1 is pulled out, all references to it1
6607 from p(it1, it2) become references to outside of the subquery and thus
6608 make the subquery (i.e. its semi-join nest) correlated.
6609 Making the subquery (i.e. its semi-join nest) correlated prevents us from
6610 using Materialization or LooseScan to execute it.
6611 */
6612
6613 20542 static bool pull_out_semijoin_tables(JOIN *join) {
6614
1/2
✓ Branch 0 taken 20542 times.
✗ Branch 1 not taken.
20542 DBUG_TRACE;
6615
6616
2/4
✓ Branch 0 taken 20542 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20542 times.
20542 assert(!join->query_block->sj_nests.empty());
6617
6618 20542 Opt_trace_context *const trace = &join->thd->opt_trace;
6619
1/2
✓ Branch 0 taken 20542 times.
✗ Branch 1 not taken.
20542 Opt_trace_object trace_wrapper(trace);
6620
1/2
✓ Branch 0 taken 20542 times.
✗ Branch 1 not taken.
20542 Opt_trace_array trace_pullout(trace, "pulled_out_semijoin_tables");
6621
6622 /* Try pulling out tables from each semi-join nest */
6623
1/2
✓ Branch 0 taken 20542 times.
✗ Branch 1 not taken.
20542 for (auto sj_list_it = join->query_block->sj_nests.begin();
6624
4/6
✓ Branch 0 taken 41827 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41827 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21285 times.
✓ Branch 5 taken 20542 times.
41827 sj_list_it != join->query_block->sj_nests.end();) {
6625
1/2
✓ Branch 0 taken 21285 times.
✗ Branch 1 not taken.
21285 TABLE_LIST *sj_nest = *sj_list_it;
6626
2/2
✓ Branch 0 taken 340 times.
✓ Branch 1 taken 20945 times.
21285 if (sj_nest->is_aj_nest()) {
6627
1/2
✓ Branch 0 taken 340 times.
✗ Branch 1 not taken.
340 ++sj_list_it;
6628 340 continue;
6629 }
6630 20945 table_map pulled_tables = 0;
6631 /*
6632 Calculate set of tables within this semi-join nest that have
6633 other dependent tables. They cannot be pulled out. For example, with
6634 t1 SEMIJOIN (t2 LEFT JOIN t3 ON ...) ON t1.a=t2.pk,
6635 t2 cannot be pulled out because t3 depends on it.
6636 */
6637 20945 table_map dep_tables = 0;
6638
7/12
✓ Branch 0 taken 20945 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20945 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 38515 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 38515 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 59460 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 38515 times.
✓ Branch 11 taken 20945 times.
59460 for (TABLE_LIST *tbl : sj_nest->nested_join->join_list) {
6639
2/2
✓ Branch 0 taken 7218 times.
✓ Branch 1 taken 31297 times.
38515 if (tbl->dep_tables & sj_nest->nested_join->used_tables)
6640 7218 dep_tables |= tbl->dep_tables;
6641 }
6642 /*
6643 Find which tables we can pull out based on key dependency data.
6644 Note that pulling one table out can allow us to pull out some
6645 other tables too.
6646 */
6647 bool pulled_a_table;
6648
2/2
✓ Branch 0 taken 2927 times.
✓ Branch 1 taken 20945 times.
23872 do {
6649 23872 pulled_a_table = false;
6650
7/12
✓ Branch 0 taken 23872 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23872 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 42044 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 42044 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 65916 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 42044 times.
✓ Branch 11 taken 23872 times.
65916 for (TABLE_LIST *tbl : sj_nest->nested_join->join_list) {
6651
6/6
✓ Branch 0 taken 41815 times.
✓ Branch 1 taken 229 times.
✓ Branch 2 taken 38673 times.
✓ Branch 3 taken 3142 times.
✓ Branch 4 taken 30020 times.
✓ Branch 5 taken 12024 times.
80717 if (tbl->table && !(pulled_tables & tbl->map()) &&
6652
2/2
✓ Branch 0 taken 30020 times.
✓ Branch 1 taken 8653 times.
38673 !(dep_tables & tbl->map())) {
6653
2/2
✓ Branch 0 taken 3037 times.
✓ Branch 1 taken 26983 times.
30020 if (find_eq_ref_candidate(
6654 30020 tbl, sj_nest->nested_join->used_tables & ~pulled_tables)) {
6655 3037 pulled_a_table = true;
6656 3037 pulled_tables |= tbl->map();
6657
3/6
✓ Branch 0 taken 3037 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3037 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3037 times.
✗ Branch 5 not taken.
3037 Opt_trace_object(trace).add_utf8_table(tbl).add(
6658 "functionally_dependent", true);
6659 /*
6660 Pulling a table out of uncorrelated subquery in general makes
6661 it correlated. See the NOTE to this function.
6662 */
6663 3037 sj_nest->nested_join->sj_corr_tables |= tbl->map();
6664 3037 sj_nest->nested_join->sj_depends_on |= tbl->map();
6665 }
6666 }
6667 }
6668 } while (pulled_a_table);
6669
6670 /*
6671 Move the pulled out TABLE_LIST elements to the parents.
6672 */
6673 20945 sj_nest->nested_join->used_tables &= ~pulled_tables;
6674 20945 sj_nest->nested_join->not_null_tables &= ~pulled_tables;
6675
6676 /* sj_inner_tables is a copy of nested_join->used_tables */
6677 20945 sj_nest->sj_inner_tables = sj_nest->nested_join->used_tables;
6678
6679 20945 bool remove = false;
6680
2/2
✓ Branch 0 taken 2834 times.
✓ Branch 1 taken 18111 times.
20945 if (pulled_tables) {
6681 2834 mem_root_deque<TABLE_LIST *> *upper_join_list =
6682 2834 (sj_nest->embedding != nullptr)
6683
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 2744 times.
2834 ? &sj_nest->embedding->nested_join->join_list
6684 2744 : &join->query_block->top_join_list;
6685
6686
1/2
✓ Branch 0 taken 2834 times.
✗ Branch 1 not taken.
2834 Prepared_stmt_arena_holder ps_arena_holder(join->thd);
6687
6688
1/2
✓ Branch 0 taken 2834 times.
✗ Branch 1 not taken.
2834 for (auto child_li = sj_nest->nested_join->join_list.begin();
6689
4/6
✓ Branch 0 taken 6153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6153 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3319 times.
✓ Branch 5 taken 2834 times.
6153 child_li != sj_nest->nested_join->join_list.end();) {
6690
1/2
✓ Branch 0 taken 3319 times.
✗ Branch 1 not taken.
3319 TABLE_LIST *tbl = *child_li;
6691
5/6
✓ Branch 0 taken 3319 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3037 times.
✓ Branch 3 taken 282 times.
✓ Branch 4 taken 3037 times.
✓ Branch 5 taken 282 times.
3319 if (tbl->table && !(sj_nest->nested_join->used_tables & tbl->map())) {
6692 /*
6693 Pull the table up in the same way as simplify_joins() does:
6694 update join_list and embedding pointers but keep next[_local]
6695 pointers.
6696 */
6697
1/2
✓ Branch 0 taken 3037 times.
✗ Branch 1 not taken.
3037 child_li = sj_nest->nested_join->join_list.erase(child_li);
6698
6699
1/2
✓ Branch 0 taken 3037 times.
✗ Branch 1 not taken.
3037 upper_join_list->push_back(tbl);
6700
6701 3037 tbl->join_list = upper_join_list;
6702 3037 tbl->embedding = sj_nest->embedding;
6703 } else {
6704
1/2
✓ Branch 0 taken 282 times.
✗ Branch 1 not taken.
282 ++child_li;
6705 }
6706 }
6707
6708 /* Remove the sj-nest itself if we've removed everything from it */
6709
2/2
✓ Branch 0 taken 2556 times.
✓ Branch 1 taken 278 times.
2834 if (!sj_nest->nested_join->used_tables) {
6710
4/8
✓ Branch 0 taken 2556 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2556 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2556 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2556 times.
✗ Branch 7 not taken.
2556 upper_join_list->erase(std::find(upper_join_list->begin(),
6711 upper_join_list->end(), sj_nest));
6712 /* Also remove it from the list of SJ-nests: */
6713 2556 remove = true;
6714 }
6715 2834 }
6716
6717
2/2
✓ Branch 0 taken 2556 times.
✓ Branch 1 taken 18389 times.
20945 if (remove) {
6718
1/2
✓ Branch 0 taken 2556 times.
✗ Branch 1 not taken.
2556 sj_list_it = join->query_block->sj_nests.erase(sj_list_it);
6719 } else {
6720
1/2
✓ Branch 0 taken 18389 times.
✗ Branch 1 not taken.
18389 ++sj_list_it;
6721 }
6722 }
6723 20542 return false;
6724 20542 }
6725
6726 /* Values in optimize */
6727 #define KEY_OPTIMIZE_EXISTS 1
6728 #define KEY_OPTIMIZE_REF_OR_NULL 2
6729
6730 /**
6731 Merge new key definitions to old ones, remove those not used in both.
6732
6733 This is called for OR between different levels.
6734
6735 To be able to do 'ref_or_null' we merge a comparison of a column
6736 and 'column IS NULL' to one test. This is useful for sub select queries
6737 that are internally transformed to something like:.
6738
6739 @code
6740 SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
6741 @endcode
6742
6743 Key_field::null_rejecting is processed as follows: @n
6744 result has null_rejecting=true if it is set for both ORed references.
6745 for example:
6746 - (t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true
6747 - (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false
6748
6749 @todo
6750 The result of this is that we're missing some 'ref' accesses.
6751 OptimizerTeam: Fix this
6752 */
6753
6754 41494 static Key_field *merge_key_fields(Key_field *start, Key_field *new_fields,
6755 Key_field *end, uint and_level) {
6756
2/2
✓ Branch 0 taken 37846 times.
✓ Branch 1 taken 3648 times.
41494 if (start == new_fields) return start; // Impossible or
6757
2/2
✓ Branch 0 taken 349 times.
✓ Branch 1 taken 3299 times.
3648 if (new_fields == end) return start; // No new fields, skip all
6758
6759 3299 Key_field *first_free = new_fields;
6760
6761 /* Mark all found fields in old array */
6762
2/2
✓ Branch 0 taken 4254 times.
✓ Branch 1 taken 3299 times.
7553 for (; new_fields != end; new_fields++) {
6763 4254 const Field *const new_field = new_fields->item_field->field;
6764
6765
2/2
✓ Branch 0 taken 33057 times.
✓ Branch 1 taken 2661 times.
35718 for (Key_field *old = start; old != first_free; old++) {
6766 33057 const Field *const old_field = old->item_field->field;
6767
6768 /*
6769 Check that the Field objects are the same, as we may have several
6770 Item_field objects pointing to the same Field:
6771 */
6772
2/2
✓ Branch 0 taken 6742 times.
✓ Branch 1 taken 26315 times.
33057 if (old_field == new_field) {
6773 /*
6774 NOTE: below const_item() call really works as "!used_tables()", i.e.
6775 it can return false where it is feasible to make it return true.
6776
6777 The cause is as follows: Some of the tables are already known to be
6778 const tables (the detection code is in JOIN::make_join_plan(),
6779 above the update_ref_and_keys() call), but we didn't propagate
6780 information about this: TABLE::const_table is not set to true, and
6781 Item::update_used_tables() hasn't been called for each item.
6782 The result of this is that we're missing some 'ref' accesses.
6783 TODO: OptimizerTeam: Fix this
6784 */
6785
2/2
✓ Branch 0 taken 3748 times.
✓ Branch 1 taken 2994 times.
6742 if (!new_fields->val->const_item()) {
6786 /*
6787 If the value matches, we can use the key reference.
6788 If not, we keep it until we have examined all new values
6789 */
6790
2/2
✓ Branch 0 taken 534 times.
✓ Branch 1 taken 3214 times.
3748 if (old->val->eq(new_fields->val, old_field->binary())) {
6791 534 old->level = and_level;
6792 534 old->optimize =
6793 534 ((old->optimize & new_fields->optimize & KEY_OPTIMIZE_EXISTS) |
6794 534 ((old->optimize | new_fields->optimize) &
6795 KEY_OPTIMIZE_REF_OR_NULL));
6796 534 old->null_rejecting =
6797
2/4
✓ Branch 0 taken 534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 534 times.
✗ Branch 3 not taken.
534 (old->null_rejecting && new_fields->null_rejecting);
6798 }
6799
4/6
✓ Branch 0 taken 2994 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2994 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 294 times.
✓ Branch 5 taken 2700 times.
5988 } else if (old->eq_func && new_fields->eq_func &&
6800
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 2700 times.
2994 old->val->eq_by_collation(new_fields->val,
6801 2994 old_field->binary(),
6802 2994 old_field->charset())) {
6803 294 old->level = and_level;
6804 294 old->optimize =
6805 294 ((old->optimize & new_fields->optimize & KEY_OPTIMIZE_EXISTS) |
6806 294 ((old->optimize | new_fields->optimize) &
6807 KEY_OPTIMIZE_REF_OR_NULL));
6808 294 old->null_rejecting =
6809
3/4
✓ Branch 0 taken 262 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 262 times.
✗ Branch 3 not taken.
294 (old->null_rejecting && new_fields->null_rejecting);
6810
4/6
✓ Branch 0 taken 2700 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2700 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1007 times.
✓ Branch 5 taken 1693 times.
5400 } else if (old->eq_func && new_fields->eq_func &&
6811
4/4
✓ Branch 0 taken 1970 times.
✓ Branch 1 taken 730 times.
✓ Branch 2 taken 1855 times.
✓ Branch 3 taken 115 times.
2700 ((old->val->const_item() && old->val->is_null()) ||
6812
2/2
✓ Branch 0 taken 892 times.
✓ Branch 1 taken 1693 times.
2585 new_fields->val->is_null())) {
6813 /* field = expression OR field IS NULL */
6814 1007 old->level = and_level;
6815 1007 old->optimize = KEY_OPTIMIZE_REF_OR_NULL;
6816 /*
6817 Remember the NOT NULL value unless the value does not depend
6818 on other tables.
6819 */
6820
6/6
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 707 times.
✓ Branch 2 taken 115 times.
✓ Branch 3 taken 185 times.
✓ Branch 4 taken 115 times.
✓ Branch 5 taken 892 times.
1007 if (!old->val->used_tables() && old->val->is_null())
6821 115 old->val = new_fields->val;
6822 /* The referred expression can be NULL: */
6823 1007 old->null_rejecting = false;
6824 } else {
6825 /*
6826 We are comparing two different const. In this case we can't
6827 use a key-lookup on this so it's better to remove the value
6828 and let the range optimizer handle it
6829 */
6830
2/2
✓ Branch 0 taken 1593 times.
✓ Branch 1 taken 100 times.
1693 if (old == --first_free) // If last item
6831 1593 break;
6832 100 *old = *first_free; // Remove old value
6833 100 old--; // Retry this value
6834 }
6835 }
6836 }
6837 }
6838 /* Remove all not used items */
6839
2/2
✓ Branch 0 taken 2645 times.
✓ Branch 1 taken 2687 times.
5332 for (Key_field *old = start; old != first_free;) {
6840
2/2
✓ Branch 0 taken 885 times.
✓ Branch 1 taken 1760 times.
2645 if (old->level != and_level) { // Not used in all levels
6841
2/2
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 273 times.
885 if (old == --first_free) break;
6842 273 *old = *first_free; // Remove old value
6843 273 continue;
6844 }
6845 1760 old++;
6846 }
6847 3299 return first_free;
6848 }
6849
6850 /**
6851 Given a field, return its index in semi-join's select list, or UINT_MAX
6852
6853 @param item_field Field to be looked up in select list
6854
6855 @retval =UINT_MAX Field is not from a semijoin-transformed subquery
6856 @retval <UINT_MAX Index in select list of subquery
6857
6858 @details
6859 Given a field, find its table; then see if the table is within a
6860 semi-join nest and if the field was in select list of the subquery
6861 (if subquery was part of a quantified comparison predicate), or
6862 the field was a result of subquery decorrelation.
6863 If it was, then return the field's index in the select list.
6864 The value is used by LooseScan strategy.
6865 */
6866
6867 4475135 static uint get_semi_join_select_list_index(Item_field *item_field) {
6868 4475135 TABLE_LIST *emb_sj_nest = item_field->table_ref->embedding;
6869
6/6
✓ Branch 0 taken 24216 times.
✓ Branch 1 taken 4450919 times.
✓ Branch 2 taken 21415 times.
✓ Branch 3 taken 2801 times.
✓ Branch 4 taken 21415 times.
✓ Branch 5 taken 4453720 times.
4475135 if (emb_sj_nest && emb_sj_nest->is_sj_or_aj_nest()) {
6870 21415 const mem_root_deque<Item *> &items =
6871 21415 emb_sj_nest->nested_join->sj_inner_exprs;
6872
2/2
✓ Branch 0 taken 22522 times.
✓ Branch 1 taken 15667 times.
38189 for (size_t i = 0; i < items.size(); i++) {
6873 22522 const Item *sel_item = items[i];
6874
4/4
✓ Branch 0 taken 10187 times.
✓ Branch 1 taken 12333 times.
✓ Branch 2 taken 5746 times.
✓ Branch 3 taken 16774 times.
32707 if (sel_item->type() == Item::FIELD_ITEM &&
6875
2/2
✓ Branch 0 taken 5746 times.
✓ Branch 1 taken 4441 times.
10187 down_cast<const Item_field *>(sel_item)->field->eq(item_field->field))
6876 5746 return i;
6877 }
6878 }
6879 4469387 return UINT_MAX;
6880 }
6881
6882 /**
6883 @brief
6884 If EXPLAIN or if the --safe-updates option is enabled, add a warning that an
6885 index cannot be used for ref access.
6886
6887 @details
6888 If EXPLAIN or if the --safe-updates option is enabled, add a warning for each
6889 index that cannot be used for ref access due to either type conversion or
6890 different collations on the field used for comparison
6891
6892 Example type conversion (char compared to int):
6893
6894 CREATE TABLE t1 (url char(1) PRIMARY KEY);
6895 SELECT * FROM t1 WHERE url=1;
6896
6897 Example different collations (danish vs german2):
6898
6899 CREATE TABLE t1 (url char(1) PRIMARY KEY) collate latin1_danish_ci;
6900 SELECT * FROM t1 WHERE url='1' collate latin1_german2_ci;
6901
6902 @param thd Thread for the connection that submitted the query
6903 @param field Field used in comparison
6904 @param cant_use_index Indexes that cannot be used for lookup
6905 */
6906 2042 static void warn_index_not_applicable(THD *thd, const Field *field,
6907 const Key_map cant_use_index) {
6908
1/2
✓ Branch 0 taken 2042 times.
✗ Branch 1 not taken.
2042 Functional_index_error_handler functional_index_error_handler(field, thd);
6909
6910
4/4
✓ Branch 0 taken 1519 times.
✓ Branch 1 taken 523 times.
✓ Branch 2 taken 526 times.
✓ Branch 3 taken 1516 times.
3561 if (thd->lex->is_explain() ||
6911
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1516 times.
1519 thd->variables.option_bits & OPTION_SAFE_UPDATES)
6912
2/2
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 526 times.
1137 for (uint j = 0; j < field->table->s->keys; j++)
6913
2/2
✓ Branch 0 taken 517 times.
✓ Branch 1 taken 94 times.
611 if (cant_use_index.is_set(j))
6914
1/2
✓ Branch 0 taken 517 times.
✗ Branch 1 not taken.
517 push_warning_printf(thd, Sql_condition::SL_WARNING,
6915 ER_WARN_INDEX_NOT_APPLICABLE,
6916 ER_THD(thd, ER_WARN_INDEX_NOT_APPLICABLE), "ref",
6917
1/2
✓ Branch 0 taken 517 times.
✗ Branch 1 not taken.
517 field->table->key_info[j].name, field->field_name);
6918 2042 }
6919
6920 /**
6921 Add a possible key to array of possible keys if it's usable as a key
6922
6923 @param [in,out] key_fields Used as an input parameter in the sense that it is
6924 a pointer to a pointer to a memory area where an array of Key_field objects
6925 will stored. It is used as an out parameter in the sense that the pointer will
6926 be updated to point beyond the last Key_field written.
6927
6928 @param thd session context
6929 @param and_level And level, to be stored in Key_field
6930 @param cond Condition predicate
6931 @param item_field Field used in comparison
6932 @param eq_func True if we used =, <=> or IS NULL
6933 @param value Array of values used for comparison with field
6934 @param num_values Number of elements in the array of values
6935 @param usable_tables Tables which can be used for key optimization
6936 @param sargables IN/OUT Array of found sargable candidates.
6937 Will be ignored in case eq_func is true.
6938
6939 @note
6940 If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
6941 table, we store this to be able to do not exists optimization later.
6942
6943
6944 @returns false if success, true if error
6945 */
6946
6947 6797105 static bool add_key_field(THD *thd, Key_field **key_fields, uint and_level,
6948 Item_func *cond, Item_field *item_field, bool eq_func,
6949 Item **value, uint num_values,
6950 table_map usable_tables, SARGABLE_PARAM **sargables) {
6951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6797196 times.
6797105 assert(cond->is_bool_func());
6952
3/4
✓ Branch 0 taken 601143 times.
✓ Branch 1 taken 6196053 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 601143 times.
6797196 assert(eq_func || sargables);
6953
47/48
✓ Branch 0 taken 6562678 times.
✓ Branch 1 taken 234513 times.
✓ Branch 2 taken 6374698 times.
✓ Branch 3 taken 187986 times.
✓ Branch 4 taken 6353512 times.
✓ Branch 5 taken 21221 times.
✓ Branch 6 taken 6343727 times.
✓ Branch 7 taken 9776 times.
✓ Branch 8 taken 6337734 times.
✓ Branch 9 taken 5940 times.
✓ Branch 10 taken 6332287 times.
✓ Branch 11 taken 5430 times.
✓ Branch 12 taken 392171 times.
✓ Branch 13 taken 5940100 times.
✓ Branch 14 taken 389532 times.
✓ Branch 15 taken 2639 times.
✓ Branch 16 taken 193861 times.
✓ Branch 17 taken 195671 times.
✓ Branch 18 taken 176379 times.
✓ Branch 19 taken 17482 times.
✓ Branch 20 taken 168157 times.
✓ Branch 21 taken 8222 times.
✓ Branch 22 taken 146865 times.
✓ Branch 23 taken 21292 times.
✓ Branch 24 taken 1162 times.
✓ Branch 25 taken 145703 times.
✓ Branch 26 taken 721 times.
✓ Branch 27 taken 441 times.
✓ Branch 28 taken 639 times.
✓ Branch 29 taken 82 times.
✓ Branch 30 taken 454 times.
✓ Branch 31 taken 185 times.
✓ Branch 32 taken 336 times.
✓ Branch 33 taken 118 times.
✓ Branch 34 taken 253 times.
✓ Branch 35 taken 83 times.
✓ Branch 36 taken 194 times.
✓ Branch 37 taken 59 times.
✓ Branch 38 taken 186 times.
✓ Branch 39 taken 8 times.
✓ Branch 40 taken 176 times.
✓ Branch 41 taken 10 times.
✓ Branch 42 taken 108 times.
✓ Branch 43 taken 68 times.
✓ Branch 44 taken 31 times.
✓ Branch 45 taken 77 times.
✓ Branch 46 taken 44 times.
✗ Branch 47 not taken.
6797196 assert(cond->functype() == Item_func::EQ_FUNC ||
6954 cond->functype() == Item_func::NE_FUNC ||
6955 cond->functype() == Item_func::GT_FUNC ||
6956 cond->functype() == Item_func::LT_FUNC ||
6957 cond->functype() == Item_func::GE_FUNC ||
6958 cond->functype() == Item_func::LE_FUNC ||
6959 cond->functype() == Item_func::MULT_EQUAL_FUNC ||
6960 cond->functype() == Item_func::EQUAL_FUNC ||
6961 cond->functype() == Item_func::LIKE_FUNC ||
6962 cond->functype() == Item_func::ISNULL_FUNC ||
6963 cond->functype() == Item_func::ISNOTNULL_FUNC ||
6964 cond->functype() == Item_func::BETWEEN ||
6965 cond->functype() == Item_func::IN_FUNC ||
6966 cond->functype() == Item_func::MEMBER_OF_FUNC ||
6967 cond->functype() == Item_func::SP_EQUALS_FUNC ||
6968 cond->functype() == Item_func::SP_WITHIN_FUNC ||
6969 cond->functype() == Item_func::SP_CONTAINS_FUNC ||
6970 cond->functype() == Item_func::SP_INTERSECTS_FUNC ||
6971 cond->functype() == Item_func::SP_DISJOINT_FUNC ||
6972 cond->functype() == Item_func::SP_COVERS_FUNC ||
6973 cond->functype() == Item_func::SP_COVEREDBY_FUNC ||
6974 cond->functype() == Item_func::SP_OVERLAPS_FUNC ||
6975 cond->functype() == Item_func::SP_TOUCHES_FUNC ||
6976 cond->functype() == Item_func::SP_CROSSES_FUNC);
6977
6978 6797093 Field *const field = item_field->field;
6979 6797093 TABLE_LIST *const tl = item_field->table_ref;
6980
6981
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6797093 times.
6797093 if (tl->table->reginfo.join_tab == nullptr) {
6982 /*
6983 Due to a bug in IN-to-EXISTS (grep for real_item() in item_subselect.cc
6984 for more info), an index over a field from an outer query might be
6985 considered here, which is incorrect. Their query has been fully
6986 optimized already so their reginfo.join_tab is NULL and we reject them.
6987 */
6988 return false;
6989 }
6990
6991
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6797101 times.
6797093 DBUG_PRINT("info", ("add_key_field for field %s", field->field_name));
6992 6797117 uint exists_optimize = 0;
6993
6/6
✓ Branch 0 taken 6797116 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2828 times.
✓ Branch 3 taken 6794283 times.
✓ Branch 4 taken 2508 times.
✓ Branch 5 taken 6794604 times.
6799945 if (!tl->derived_keys_ready && tl->uses_materialization() &&
6994
2/2
✓ Branch 0 taken 2508 times.
✓ Branch 1 taken 320 times.
2828 !tl->table->is_created()) {
6995 bool allocated;
6996
2/4
✓ Branch 0 taken 2508 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2508 times.
2508 if (tl->update_derived_keys(thd, field, value, num_values, &allocated))
6997 87 return true;
6998
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 2421 times.
2508 if (!allocated) return false;
6999 }
7000
2/2
✓ Branch 0 taken 1174432 times.
✓ Branch 1 taken 5622514 times.
6797025 if (!field->is_flag_set(PART_KEY_FLAG)) {
7001 // Don't remove column IS NULL on a LEFT JOIN table
7002
2/2
✓ Branch 0 taken 11388 times.
✓ Branch 1 taken 1022517 times.
1033905 if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
7003
8/8
✓ Branch 0 taken 1033905 times.
✓ Branch 1 taken 140527 times.
✓ Branch 2 taken 893 times.
✓ Branch 3 taken 10495 times.
✓ Branch 4 taken 717 times.
✓ Branch 5 taken 203 times.
✓ Branch 6 taken 1174256 times.
✓ Branch 7 taken 203 times.
2208337 !tl->table->is_nullable() || field->is_nullable())
7004 1174256 return false; // Not a key. Skip it
7005 203 exists_optimize = KEY_OPTIMIZE_EXISTS;
7006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 203 times.
203 assert(num_values == 1);
7007 } else {
7008 5622514 table_map used_tables = 0;
7009 5622514 bool optimizable = false;
7010
2/2
✓ Branch 0 taken 5980549 times.
✓ Branch 1 taken 5622588 times.
11603137 for (uint i = 0; i < num_values; i++) {
7011 5980549 used_tables |= (value[i])->used_tables();
7012
2/2
✓ Branch 0 taken 5973300 times.
✓ Branch 1 taken 7323 times.
5980594 if (!((value[i])->used_tables() & (tl->map() | RAND_TABLE_BIT)))
7013 5973300 optimizable = true;
7014 }
7015
2/2
✓ Branch 0 taken 7240 times.
✓ Branch 1 taken 5615348 times.
5622588 if (!optimizable) return false;
7016
2/2
✓ Branch 0 taken 680266 times.
✓ Branch 1 taken 4935070 times.
5615348 if (!(usable_tables & tl->map())) {
7017
2/2
✓ Branch 0 taken 2013 times.
✓ Branch 1 taken 677139 times.
679155 if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
7018
8/8
✓ Branch 0 taken 679155 times.
✓ Branch 1 taken 1111 times.
✓ Branch 2 taken 1998 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 1836 times.
✓ Branch 5 taken 165 times.
✓ Branch 6 taken 680103 times.
✓ Branch 7 taken 163 times.
1359418 !tl->table->is_nullable() || field->is_nullable())
7019 680103 return false; // Can't use left join optimize
7020 163 exists_optimize = KEY_OPTIMIZE_EXISTS;
7021 } else {
7022 4935070 JOIN_TAB *stat = tl->table->reginfo.join_tab;
7023 4935070 Key_map possible_keys = field->key_start;
7024 4935070 possible_keys.intersect(tl->table->keys_in_use_for_query);
7025 4935056 stat[0].keys().merge(possible_keys); // Add possible keys
7026
7027 /*
7028 Save the following cases:
7029 Field op constant
7030 Field LIKE constant where constant doesn't start with a wildcard
7031 Field = field2 where field2 is in a different table
7032 Field op formula
7033 Field IS NULL
7034 Field IS NOT NULL
7035 Field BETWEEN ...
7036 Field IN ...
7037 */
7038 4935081 stat[0].key_dependent |= used_tables;
7039
7040 4935081 bool is_const = true;
7041
2/2
✓ Branch 0 taken 5292895 times.
✓ Branch 1 taken 1134786 times.
6427681 for (uint i = 0; i < num_values; i++) {
7042
3/4
✓ Branch 0 taken 5292945 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3800345 times.
✓ Branch 3 taken 1492600 times.
5292895 if (!(is_const &= value[i]->const_for_execution())) break;
7043 }
7044
2/2
✓ Branch 0 taken 1134790 times.
✓ Branch 1 taken 3800341 times.
4935131 if (is_const)
7045 1134790 stat[0].const_keys.merge(possible_keys);
7046
2/2
✓ Branch 0 taken 1789 times.
✓ Branch 1 taken 3798552 times.
3800341 else if (!eq_func) {
7047 /*
7048 Save info to be able check whether this predicate can be
7049 considered as sargable for range analysis after reading const tables.
7050 We do not save info about equalities as update_const_equal_items
7051 will take care of updating info on keys from sargable equalities.
7052 */
7053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1789 times.
1789 assert(sargables);
7054 1789 (*sargables)--;
7055 /*
7056 The sargables and key_fields arrays share the same memory
7057 buffer, and grow from opposite directions, so make sure they
7058 don't cross.
7059 */
7060
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1789 times.
1789 assert(*sargables > reinterpret_cast<SARGABLE_PARAM *>(*key_fields));
7061 1789 (*sargables)->field = field;
7062 1789 (*sargables)->arg_value = value;
7063 1789 (*sargables)->num_values = num_values;
7064 }
7065 /*
7066 We can't always use indexes when comparing a string index to a
7067 number. cmp_type() is checked to allow compare of dates to numbers.
7068 eq_func is NEVER true when num_values > 1
7069 */
7070
2/2
✓ Branch 0 taken 458267 times.
✓ Branch 1 taken 4476848 times.
4937157 if (!eq_func) return false;
7071
7072 /*
7073 Check if the field and value are comparable in the index.
7074 */
7075
2/4
✓ Branch 0 taken 4476837 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4476837 times.
✗ Branch 3 not taken.
4476848 if (!comparable_in_index(cond, field, Field::itRAW, cond->functype(),
7076
4/4
✓ Branch 0 taken 4475014 times.
✓ Branch 1 taken 1823 times.
✓ Branch 2 taken 2042 times.
✓ Branch 3 taken 4474773 times.
8951829 *value) ||
7077
3/4
✓ Branch 0 taken 4474980 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 749089 times.
✓ Branch 3 taken 3725891 times.
4475014 (field->cmp_type() == STRING_RESULT &&
7078
3/4
✓ Branch 0 taken 749091 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 748747 times.
✓ Branch 3 taken 344 times.
749089 field->match_collation_to_optimize_range() &&
7079
4/6
✓ Branch 0 taken 748737 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 748757 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 219 times.
✓ Branch 5 taken 748538 times.
748747 field->charset() != cond->compare_collation())) {
7080
1/2
✓ Branch 0 taken 2042 times.
✗ Branch 1 not taken.
2042 warn_index_not_applicable(stat->join()->thd, field, possible_keys);
7081 2042 return false;
7082 }
7083 }
7084 }
7085 /*
7086 For the moment eq_func is always true. This slot is reserved for future
7087 extensions where we want to remembers other things than just eq comparisons
7088 */
7089
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4475139 times.
4475139 assert(eq_func);
7090 /*
7091 Calculate the "null rejecting" property based on the type of predicate.
7092 Only the <=> operator and the IS NULL and IS NOT NULL clauses may return
7093 true on nullable operands that have the NULL value - assuming that all
7094 other predicates are augmented with IS TRUE or IS FALSE truth clause,
7095 so that all UNKNOWN results are converted to TRUE or FALSE.
7096
7097 The "null rejecting" property can be combined with the left and right
7098 operands to perform certain optimizations.
7099
7100 If the condition has form "left.field = right.keypart" and left.field can
7101 be NULL, there will be no matches if left.field is NULL.
7102 We use null_rejecting in add_not_null_conds() to add
7103 'left.field IS NOT NULL' to tab->m_condition, if this is not an outer
7104 join. We also use it to shortcut reading rows from table "right" when
7105 left.field is found to be a NULL value (in RefIterator and BKA).
7106
7107 It is also possible to apply optimizations to the indexed table.
7108 If the operation is null rejecting and there is a unique index over
7109 the key field, an eq_ref operation can be performed on the index, since
7110 we have no interest in the NULL values.
7111
7112 Notice however that the null rejecting property may be cancelled out
7113 by the KEY_OPTIMIZE_REF_OR_NULL property: this can be set when having:
7114
7115 left.field = right.keypart OR right.keypart IS NULL.
7116 */
7117 4475139 const bool null_rejecting = cond->functype() != Item_func::EQUAL_FUNC &&
7118
4/4
✓ Branch 0 taken 4473822 times.
✓ Branch 1 taken 1307 times.
✓ Branch 2 taken 4469320 times.
✓ Branch 3 taken 4515 times.
8944487 cond->functype() != Item_func::ISNULL_FUNC &&
7119
1/2
✓ Branch 0 taken 4469365 times.
✗ Branch 1 not taken.
4469320 cond->functype() != Item_func::ISNOTNULL_FUNC;
7120
7121 /* Store possible eq field */
7122 4475130 new (*key_fields) Key_field(item_field, *value, and_level, exists_optimize,
7123 eq_func, null_rejecting, nullptr,
7124 4475180 get_semi_join_select_list_index(item_field));
7125 4475172 (*key_fields)++;
7126 /*
7127 The sargables and key_fields arrays share the same memory buffer,
7128 and grow from opposite directions, so make sure they don't
7129 cross. But if sargables was NULL, eq_func had to be true and we
7130 don't write any sargables.
7131 */
7132
3/4
✓ Branch 0 taken 4474704 times.
✓ Branch 1 taken 468 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4474704 times.
4475172 assert(sargables == nullptr ||
7133 *key_fields < reinterpret_cast<Key_field *>(*sargables));
7134
7135 4475172 return false;
7136 }
7137
7138 /**
7139 Add possible keys to array of possible keys originated from a simple
7140 predicate.
7141
7142 @param thd session context
7143 @param[in,out] key_fields Pointer to add key, if usable
7144 is incremented if key was stored in the array
7145 @param and_level And level, to be stored in Key_field
7146 @param cond Condition predicate
7147 @param field_item Field used in comparison
7148 @param eq_func True if we used =, <=> or IS NULL
7149 @param val Value used for comparison with field
7150 Is NULL for BETWEEN and IN
7151 @param num_values Number of elements in the array of values
7152 @param usable_tables Tables which can be used for key optimization
7153 @param sargables IN/OUT Array of found sargable candidates
7154
7155 @note
7156 If field items f1 and f2 belong to the same multiple equality and
7157 a key is added for f1, the the same key is added for f2.
7158
7159 @returns false if success, true if error
7160 */
7161
7162 850711 static bool add_key_equal_fields(THD *thd, Key_field **key_fields,
7163 uint and_level, Item_func *cond,
7164 Item_field *field_item, bool eq_func,
7165 Item **val, uint num_values,
7166 table_map usable_tables,
7167 SARGABLE_PARAM **sargables) {
7168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 850711 times.
850711 assert(cond->is_bool_func());
7169
7170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 850711 times.
850711 if (add_key_field(thd, key_fields, and_level, cond, field_item, eq_func, val,
7171 num_values, usable_tables, sargables))
7172 return true;
7173 850711 Item_equal *item_equal = field_item->item_equal;
7174
2/2
✓ Branch 0 taken 845283 times.
✓ Branch 1 taken 5428 times.
850711 if (item_equal == nullptr) return false;
7175 /*
7176 Add to the set of possible key values every substitution of
7177 the field for an equal field included into item_equal
7178 */
7179
5/8
✓ Branch 0 taken 5428 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5428 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16450 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11022 times.
✓ Branch 7 taken 5428 times.
16450 for (Item_field &item : item_equal->get_fields()) {
7180
3/4
✓ Branch 0 taken 11022 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5594 times.
✓ Branch 3 taken 5428 times.
11022 if (!field_item->field->eq(item.field)) {
7181
2/4
✓ Branch 0 taken 5594 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5594 times.
5594 if (add_key_field(thd, key_fields, and_level, cond, &item, eq_func, val,
7182 num_values, usable_tables, sargables))
7183 return true;
7184 }
7185 }
7186 5428 return false;
7187 }
7188
7189 /**
7190 Check if an expression is a non-outer field.
7191
7192 Checks if an expression is a field and belongs to the current select.
7193
7194 @param field Item expression to check
7195
7196 @return boolean
7197 @retval true the expression is a local field
7198 @retval false it's something else
7199 */
7200
7201 2231340 static bool is_local_field(Item *field) {
7202 2231340 return field->real_item()->type() == Item::FIELD_ITEM &&
7203
2/2
✓ Branch 0 taken 850649 times.
✓ Branch 1 taken 5208 times.
855857 !field->is_outer_reference() &&
7204
4/4
✓ Branch 0 taken 855857 times.
✓ Branch 1 taken 1375544 times.
✓ Branch 2 taken 850620 times.
✓ Branch 3 taken 29 times.
3937867 !down_cast<Item_ident *>(field)->depended_from &&
7205
1/2
✓ Branch 0 taken 850620 times.
✗ Branch 1 not taken.
3082010 !down_cast<Item_ident *>(field->real_item())->depended_from;
7206 }
7207
7208 /**
7209 Check if a row constructor expression is over columns in the same query block.
7210
7211 @param item_row Row expression to check.
7212
7213 @return boolean
7214 @retval true The expression is a local column reference.
7215 @retval false It's something else.
7216 */
7217 177 static bool is_row_of_local_columns(Item_row *item_row) {
7218
2/2
✓ Branch 0 taken 371 times.
✓ Branch 1 taken 157 times.
528 for (uint i = 0; i < item_row->cols(); ++i)
7219
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 351 times.
371 if (!is_local_field(item_row->element_index(i))) return false;
7220 157 return true;
7221 }
7222
7223 /**
7224 The guts of the ref optimizer. This function, along with the other
7225 add_key_* functions, make up a recursive procedure that analyzes a
7226 condition expression (a tree of AND and OR predicates) and does
7227 many things.
7228
7229 @param thd session context
7230 @param join The query block involving the condition.
7231 @param [in,out] key_fields Start of memory buffer, see below.
7232 @param [in,out] and_level Current 'and level', see below.
7233 @param cond The conditional expression to analyze.
7234 @param usable_tables Tables not in this bitmap will not be examined.
7235 @param [in,out] sargables End of memory buffer, see below.
7236
7237 @returns false if success, true if error
7238
7239 This documentation is the result of reverse engineering and may
7240 therefore not capture the full gist of the procedure, but it is
7241 known to do the following:
7242
7243 - Populate a raw memory buffer from two directions at the same time. An
7244 'array' of Key_field objects fill the buffer from low to high addresses
7245 whilst an 'array' of SARGABLE_PARAM's fills the buffer from high to low
7246 addresses. At the first call to this function, it is assumed that
7247 key_fields points to the beginning of the buffer and sargables point to the
7248 end (except for a poor-mans 'null element' at the very end).
7249
7250 - Update a number of properties in the JOIN_TAB's that can be used
7251 to find search keys (sargables).
7252
7253 - JOIN_TAB::keys
7254 - JOIN_TAB::key_dependent
7255 - JOIN_TAB::const_keys (dictates if the range optimizer will be run
7256 later.)
7257
7258 The Key_field objects are marked with something called an 'and_level', which
7259 does @b not correspond to their nesting depth within the expression tree. It
7260 is rather a tag to group conjunctions together. For instance, in the
7261 conditional expression
7262
7263 @code
7264 a = 0 AND b = 0
7265 @endcode
7266
7267 two Key_field's are produced, both having an and_level of 0.
7268
7269 In an expression such as
7270
7271 @code
7272 a = 0 AND b = 0 OR a = 1
7273 @endcode
7274
7275 three Key_field's are produced, the first two corresponding to 'a = 0' and
7276 'b = 0', respectively, both with and_level 0. The third one corresponds to
7277 'a = 1' and has an and_level of 1.
7278
7279 A separate function, merge_key_fields() performs ref access validation on
7280 the Key_field array on the recursice ascent. If some Key_field's cannot be
7281 used for ref access, the key_fields pointer is rolled back. All other
7282 modifications to the query plan remain.
7283 */
7284 5548730 bool add_key_fields(THD *thd, JOIN *join, Key_field **key_fields,
7285 uint *and_level, Item *cond, table_map usable_tables,
7286 SARGABLE_PARAM **sargables) {
7287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5548829 times.
5548730 assert(cond->is_bool_func());
7288
7289
2/2
✓ Branch 0 taken 860561 times.
✓ Branch 1 taken 4688258 times.
5548829 if (cond->type() == Item_func::COND_ITEM) {
7290
1/2
✓ Branch 0 taken 860588 times.
✗ Branch 1 not taken.
860561 List_iterator_fast<Item> li(*((Item_cond *)cond)->argument_list());
7291 860588 Key_field *org_key_fields = *key_fields;
7292
7293
3/4
✓ Branch 0 taken 860569 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 835030 times.
✓ Branch 3 taken 25539 times.
860588 if (down_cast<Item_cond *>(cond)->functype() == Item_func::COND_AND_FUNC) {
7294 Item *item;
7295
2/2
✓ Branch 0 taken 3712983 times.
✓ Branch 1 taken 835046 times.
4547996 while ((item = li++)) {
7296
2/4
✓ Branch 0 taken 3712966 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3712966 times.
3712983 if (add_key_fields(thd, join, key_fields, and_level, item,
7297 usable_tables, sargables))
7298 return true;
7299 }
7300
2/2
✓ Branch 0 taken 3537916 times.
✓ Branch 1 taken 835046 times.
4372962 for (; org_key_fields != *key_fields; org_key_fields++)
7301 3537916 org_key_fields->level = *and_level;
7302 } else {
7303 25539 (*and_level)++;
7304
2/4
✓ Branch 0 taken 25539 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25539 times.
25539 if (add_key_fields(thd, join, key_fields, and_level, li++, usable_tables,
7305 sargables))
7306 return true;
7307 Item *item;
7308
2/2
✓ Branch 0 taken 41489 times.
✓ Branch 1 taken 25544 times.
67033 while ((item = li++)) {
7309 41489 Key_field *start_key_fields = *key_fields;
7310 41489 (*and_level)++;
7311
2/4
✓ Branch 0 taken 41494 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 41494 times.
41489 if (add_key_fields(thd, join, key_fields, and_level, item,
7312 usable_tables, sargables))
7313 return true;
7314 41494 *key_fields = merge_key_fields(org_key_fields, start_key_fields,
7315
1/2
✓ Branch 0 taken 41494 times.
✗ Branch 1 not taken.
41494 *key_fields, ++(*and_level));
7316 }
7317 }
7318 860590 return false;
7319 }
7320
7321 /*
7322 Subquery optimization: Conditions that are pushed down into subqueries
7323 are wrapped into Item_func_trig_cond. We process the wrapped condition
7324 but need to set cond_guard for Key_use elements generated from it.
7325 */
7326
4/4
✓ Branch 0 taken 4687706 times.
✓ Branch 1 taken 520 times.
✓ Branch 2 taken 3601 times.
✓ Branch 3 taken 4684662 times.
9376001 if (cond->type() == Item::FUNC_ITEM &&
7327
2/2
✓ Branch 0 taken 3601 times.
✓ Branch 1 taken 4684142 times.
4687706 down_cast<Item_func *>(cond)->functype() == Item_func::TRIG_COND_FUNC) {
7328 3601 Item *const cond_arg = down_cast<Item_func *>(cond)->arguments()[0];
7329
1/2
✓ Branch 0 taken 3601 times.
✗ Branch 1 not taken.
7202 if (join->group_list.empty() && join->order.empty() &&
7330
1/2
✓ Branch 0 taken 3601 times.
✗ Branch 1 not taken.
3601 join->query_expression()->item &&
7331
5/6
✓ Branch 0 taken 3601 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3261 times.
✓ Branch 3 taken 340 times.
✓ Branch 4 taken 3206 times.
✓ Branch 5 taken 395 times.
10463 join->query_expression()->item->substype() == Item_subselect::IN_SUBS &&
7332
2/2
✓ Branch 0 taken 3206 times.
✓ Branch 1 taken 55 times.
3261 !join->query_expression()->is_union()) {
7333 3206 Key_field *save = *key_fields;
7334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3206 times.
3206 if (add_key_fields(thd, join, key_fields, and_level, cond_arg,
7335 usable_tables, sargables))
7336 return true;
7337 // Indicate that this ref access candidate is for subquery lookup:
7338
2/2
✓ Branch 0 taken 918 times.
✓ Branch 1 taken 3206 times.
4124 for (; save != *key_fields; save++)
7339 918 save->cond_guard = ((Item_func_trig_cond *)cond)->get_trig_var();
7340 }
7341 3601 return false;
7342 }
7343
7344 /* If item is of type 'field op field/constant' add it to key_fields */
7345
2/2
✓ Branch 0 taken 524 times.
✓ Branch 1 taken 4684124 times.
4684662 if (cond->type() != Item::FUNC_ITEM) return false;
7346 4684124 Item_func *const cond_func = down_cast<Item_func *>(cond);
7347 4684194 auto optimize = cond_func->select_optimize(thd);
7348 // Catch errors that might be thrown during select_optimize()
7349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4684092 times.
4684181 if (thd->is_error()) return true;
7350
6/6
✓ Branch 0 taken 251706 times.
✓ Branch 1 taken 1059572 times.
✓ Branch 2 taken 456913 times.
✓ Branch 3 taken 26622 times.
✓ Branch 4 taken 2889248 times.
✓ Branch 5 taken 31 times.
4684092 switch (optimize) {
7351 251706 case Item_func::OPTIMIZE_NONE:
7352 4684038 break;
7353 1059572 case Item_func::OPTIMIZE_KEY: {
7354 Item **values;
7355 /*
7356 Build list of possible keys for 'a BETWEEN low AND high'.
7357 It is handled similar to the equivalent condition
7358 'a >= low AND a <= high':
7359 */
7360
3/4
✓ Branch 0 taken 1059587 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21873 times.
✓ Branch 3 taken 1037714 times.
1059572 if (cond_func->functype() == Item_func::BETWEEN) {
7361 Item_field *field_item;
7362 21873 bool equal_func = false;
7363 21873 uint num_values = 2;
7364
1/2
✓ Branch 0 taken 21873 times.
✗ Branch 1 not taken.
21873 values = cond_func->arguments();
7365
7366 bool binary_cmp =
7367
2/4
✓ Branch 0 taken 21873 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21873 times.
✗ Branch 3 not taken.
21873 (values[0]->real_item()->type() == Item::FIELD_ITEM)
7368
6/8
✓ Branch 0 taken 20626 times.
✓ Branch 1 taken 1247 times.
✓ Branch 2 taken 20626 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20626 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20440 times.
✓ Branch 7 taken 186 times.
21873 ? ((Item_field *)values[0]->real_item())->field->binary()
7369 21873 : true;
7370
7371 /*
7372 Additional optimization: If 'low = high':
7373 Handle as if the condition was "t.key = low".
7374 */
7375
4/4
✓ Branch 0 taken 21690 times.
✓ Branch 1 taken 183 times.
✓ Branch 2 taken 61 times.
✓ Branch 3 taken 21812 times.
43563 if (!((Item_func_between *)cond_func)->negated &&
7376
3/4
✓ Branch 0 taken 21690 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
✓ Branch 3 taken 21629 times.
21690 values[1]->eq(values[2], binary_cmp)) {
7377 61 equal_func = true;
7378 61 num_values = 1;
7379 }
7380
7381 /*
7382 Append keys for 'field <cmp> value[]' if the
7383 condition is of the form::
7384 '<field> BETWEEN value[1] AND value[2]'
7385 */
7386
3/4
✓ Branch 0 taken 21873 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20626 times.
✓ Branch 3 taken 1247 times.
21873 if (is_local_field(values[0])) {
7387
1/2
✓ Branch 0 taken 20626 times.
✗ Branch 1 not taken.
20626 field_item = (Item_field *)(values[0]->real_item());
7388
2/4
✓ Branch 0 taken 20626 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20626 times.
20626 if (add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7389 field_item, equal_func, &values[1],
7390 num_values, usable_tables, sargables))
7391 return true;
7392 }
7393 /*
7394 Append keys for 'value[0] <cmp> field' if the
7395 condition is of the form:
7396 'value[0] BETWEEN field1 AND field2'
7397 */
7398
2/2
✓ Branch 0 taken 43685 times.
✓ Branch 1 taken 21873 times.
65558 for (uint i = 1; i <= num_values; i++) {
7399
3/4
✓ Branch 0 taken 43685 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 387 times.
✓ Branch 3 taken 43298 times.
43685 if (is_local_field(values[i])) {
7400
1/2
✓ Branch 0 taken 387 times.
✗ Branch 1 not taken.
387 field_item = (Item_field *)(values[i]->real_item());
7401
2/4
✓ Branch 0 taken 387 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 387 times.
387 if (add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7402 field_item, equal_func, values, 1,
7403 usable_tables, sargables))
7404 return true;
7405 }
7406 }
7407 } // if ( ... Item_func::BETWEEN)
7408
5/6
✓ Branch 0 taken 1037691 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 464 times.
✓ Branch 3 taken 1037227 times.
✓ Branch 4 taken 441 times.
✓ Branch 5 taken 1037250 times.
1038178 else if (cond_func->functype() == Item_func::MEMBER_OF_FUNC &&
7409
4/6
✓ Branch 0 taken 464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 464 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 441 times.
✓ Branch 5 taken 23 times.
464 is_local_field(cond_func->key_item())) {
7410 // The predicate is <val> IN (<typed array>)
7411
1/2
✓ Branch 0 taken 441 times.
✗ Branch 1 not taken.
441 add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7412
3/6
✓ Branch 0 taken 441 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 441 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 436 times.
✗ Branch 5 not taken.
441 (Item_field *)(cond_func->key_item()->real_item()),
7413 true, cond_func->arguments(), 1, usable_tables,
7414 sargables);
7415
5/6
✓ Branch 0 taken 1037241 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1037112 times.
✓ Branch 3 taken 129 times.
✓ Branch 4 taken 256 times.
✓ Branch 5 taken 1037017 times.
2074394 } else if (cond_func->functype() == Item_func::JSON_CONTAINS ||
7416
3/4
✓ Branch 0 taken 1037144 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 1037027 times.
1037112 cond_func->functype() == Item_func::JSON_OVERLAPS) {
7417 /*
7418 Applicability analysis was done during substitute_gc().
7419 Check here that a typed array field is used and there's a key over
7420 it.
7421 1) func has a key item
7422 2) key item is a local field
7423 3) key item is a typed array field
7424 If so, mark appropriate index as available for range optimizer
7425 */
7426
1/2
✓ Branch 0 taken 256 times.
✗ Branch 1 not taken.
256 if (!cond_func->key_item() || // 1
7427
8/10
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 245 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 245 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 213 times.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 44 times.
✓ Branch 9 taken 212 times.
469 !is_local_field(cond_func->key_item()) || // 2
7428
4/6
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 213 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 212 times.
213 !cond_func->key_item()->returns_array()) // 3
7429 44 break;
7430 const Field *field =
7431
1/2
✓ Branch 0 taken 212 times.
✗ Branch 1 not taken.
212 (down_cast<const Item_field *>(cond_func->key_item()))->field;
7432 212 JOIN_TAB *tab = field->table->reginfo.join_tab;
7433 212 Key_map possible_keys = field->key_start;
7434
7435 212 possible_keys.intersect(field->table->keys_in_use_for_query);
7436 212 tab->keys().merge(possible_keys); // Add possible keys
7437 212 tab->const_keys.merge(possible_keys); // Add possible keys
7438 } // if (... Item_func::CONTAINS)
7439 // The predicate is IN or <>
7440
6/8
✓ Branch 0 taken 1036985 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1037039 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 332138 times.
✓ Branch 5 taken 704901 times.
✓ Branch 6 taken 332000 times.
✓ Branch 7 taken 705039 times.
1369155 else if (is_local_field(cond_func->key_item()) &&
7441
3/4
✓ Branch 0 taken 332138 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 332000 times.
✓ Branch 3 taken 138 times.
332138 !cond_func->is_outer_reference()) {
7442
1/2
✓ Branch 0 taken 332000 times.
✗ Branch 1 not taken.
332000 values = cond_func->arguments() + 1;
7443
5/6
✓ Branch 0 taken 332000 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 187274 times.
✓ Branch 3 taken 144726 times.
✓ Branch 4 taken 2055 times.
✓ Branch 5 taken 329945 times.
519274 if (cond_func->functype() == Item_func::NE_FUNC &&
7444
4/6
✓ Branch 0 taken 187274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 187274 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2055 times.
✓ Branch 5 taken 185219 times.
187274 is_local_field(cond_func->arguments()[1]))
7445 2055 values--;
7446
5/8
✓ Branch 0 taken 332000 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144726 times.
✓ Branch 3 taken 187274 times.
✓ Branch 4 taken 144726 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 144726 times.
332000 assert(cond_func->functype() != Item_func::IN_FUNC ||
7447 cond_func->argument_count() != 2);
7448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 332000 times.
332000 if (add_key_equal_fields(
7449 thd, key_fields, *and_level, cond_func,
7450
2/4
✓ Branch 0 taken 332000 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 332000 times.
✗ Branch 3 not taken.
332000 (Item_field *)(cond_func->key_item()->real_item()), false,
7451
2/4
✓ Branch 0 taken 332000 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 332000 times.
✗ Branch 3 not taken.
332000 values, cond_func->argument_count() - 1, usable_tables,
7452 sargables))
7453 return true;
7454
5/6
✓ Branch 0 taken 704981 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3289 times.
✓ Branch 3 taken 701692 times.
✓ Branch 4 taken 177 times.
✓ Branch 5 taken 704804 times.
708328 } else if (cond_func->functype() == Item_func::IN_FUNC &&
7455
4/6
✓ Branch 0 taken 3289 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3289 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 177 times.
✓ Branch 5 taken 3112 times.
3289 cond_func->key_item()->type() == Item::ROW_ITEM) {
7456 /*
7457 The condition is (column1, column2, ... ) IN ((const1_1, const1_2),
7458 ...) and there is an index on (column1, column2, ...)
7459
7460 The code below makes sure that the row constructor on the lhs indeed
7461 contains only column references before calling add_key_field on them.
7462
7463 We can't do a ref access on IN, yet here we are. Why? We need
7464 to run add_key_field() only because it verifies that there are
7465 only constant expressions in the rows on the IN's rhs, see
7466 comment above the call to add_key_field() below.
7467
7468 Actually, We could in theory do a ref access if the IN rhs
7469 contained just a single row, but there is a hack in the parser
7470 causing such IN predicates be parsed as row equalities.
7471 */
7472
1/2
✓ Branch 0 taken 177 times.
✗ Branch 1 not taken.
177 Item_row *lhs_row = static_cast<Item_row *>(cond_func->key_item());
7473
3/4
✓ Branch 0 taken 177 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 157 times.
✓ Branch 3 taken 20 times.
177 if (is_row_of_local_columns(lhs_row)) {
7474
3/4
✓ Branch 0 taken 503 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
✓ Branch 3 taken 157 times.
503 for (uint i = 0; i < lhs_row->cols(); ++i) {
7475
2/4
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
✗ Branch 3 not taken.
346 Item *const lhs_item = lhs_row->element_index(i)->real_item();
7476
2/4
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 346 times.
346 assert(lhs_item->type() == Item::FIELD_ITEM);
7477 346 Item_field *const lhs_column = static_cast<Item_field *>(lhs_item);
7478 // j goes from 1 since arguments()[0] is the lhs of IN.
7479
3/4
✓ Branch 0 taken 1082 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 346 times.
1082 for (uint j = 1; j < cond_func->argument_count(); ++j) {
7480 // Here we pick out the i:th column in the j:th row.
7481
1/2
✓ Branch 0 taken 736 times.
✗ Branch 1 not taken.
736 Item *rhs_item = cond_func->arguments()[j];
7482
2/4
✓ Branch 0 taken 736 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 736 times.
736 assert(rhs_item->type() == Item::ROW_ITEM);
7483 736 Item_row *rhs_row = static_cast<Item_row *>(rhs_item);
7484
3/6
✓ Branch 0 taken 736 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 736 times.
736 assert(rhs_row->cols() == lhs_row->cols());
7485
1/2
✓ Branch 0 taken 736 times.
✗ Branch 1 not taken.
736 Item **rhs_expr_ptr = rhs_row->addr(i);
7486 /*
7487 add_key_field() will write a Key_field on each call
7488 here, but we don't care, it will never be used. We only
7489 call it for the side effect: update JOIN_TAB::const_keys
7490 so the range optimizer can be invoked. We pass a
7491 scrap buffer and pointer here.
7492 */
7493 736 Key_field scrap_key_field = **key_fields;
7494 736 Key_field *scrap_key_field_ptr = &scrap_key_field;
7495
2/4
✓ Branch 0 taken 736 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 736 times.
736 if (add_key_field(thd, &scrap_key_field_ptr, *and_level,
7496 cond_func, lhs_column,
7497 true, // eq_func
7498 rhs_expr_ptr,
7499 1, // Number of expressions: one
7500 usable_tables,
7501 nullptr)) // sargables
7502 return true;
7503 // The pointer is not supposed to increase by more than one.
7504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 736 times.
736 assert(scrap_key_field_ptr <= &scrap_key_field + 1);
7505 }
7506 }
7507 }
7508 }
7509 1059502 break;
7510 }
7511 456913 case Item_func::OPTIMIZE_OP: {
7512
3/4
✓ Branch 0 taken 456913 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238587 times.
✓ Branch 3 taken 218326 times.
695500 bool equal_func = (cond_func->functype() == Item_func::EQ_FUNC ||
7513
3/4
✓ Branch 0 taken 238587 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2239 times.
✓ Branch 3 taken 236348 times.
238587 cond_func->functype() == Item_func::EQUAL_FUNC);
7514
7515
4/6
✓ Branch 0 taken 456913 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 456913 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 426195 times.
✓ Branch 5 taken 30718 times.
456913 if (is_local_field(cond_func->arguments()[0])) {
7516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 426195 times.
426195 if (add_key_equal_fields(
7517 thd, key_fields, *and_level, cond_func,
7518
2/4
✓ Branch 0 taken 426195 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 426195 times.
✗ Branch 3 not taken.
426195 (Item_field *)(cond_func->arguments()[0])->real_item(),
7519
2/4
✓ Branch 0 taken 426195 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 426195 times.
✗ Branch 3 not taken.
426195 equal_func, cond_func->arguments() + 1, 1, usable_tables,
7520 sargables))
7521 return true;
7522 } else {
7523
2/4
✓ Branch 0 taken 30718 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30718 times.
✗ Branch 3 not taken.
30718 Item *real_item = cond_func->arguments()[0]->real_item();
7524
3/4
✓ Branch 0 taken 30718 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17656 times.
✓ Branch 3 taken 13062 times.
30718 if (real_item->type() == Item::FUNC_ITEM) {
7525 17656 Item_func *func_item = down_cast<Item_func *>(real_item);
7526
3/4
✓ Branch 0 taken 17656 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2860 times.
✓ Branch 3 taken 14796 times.
17656 if (func_item->functype() == Item_func::COLLATE_FUNC) {
7527
1/2
✓ Branch 0 taken 2860 times.
✗ Branch 1 not taken.
2860 Item *key_item = func_item->key_item();
7528
3/4
✓ Branch 0 taken 2860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2827 times.
✓ Branch 3 taken 33 times.
2860 if (key_item->type() == Item::FIELD_ITEM) {
7529
2/4
✓ Branch 0 taken 2827 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2827 times.
2827 if (add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7530 down_cast<Item_field *>(key_item),
7531
1/2
✓ Branch 0 taken 2827 times.
✗ Branch 1 not taken.
2827 equal_func, cond_func->arguments() + 1,
7532 1, usable_tables, sargables))
7533 return true;
7534 }
7535 }
7536 }
7537 }
7538
6/8
✓ Branch 0 taken 456913 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 456913 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 42838 times.
✓ Branch 5 taken 414075 times.
✓ Branch 6 taken 42838 times.
✓ Branch 7 taken 414075 times.
499751 if (is_local_field(cond_func->arguments()[1]) &&
7539
2/4
✓ Branch 0 taken 42838 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 42838 times.
✗ Branch 3 not taken.
42838 cond_func->functype() != Item_func::LIKE_FUNC) {
7540
2/4
✓ Branch 0 taken 42838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 42838 times.
85676 if (add_key_equal_fields(
7541 thd, key_fields, *and_level, cond_func,
7542
3/6
✓ Branch 0 taken 42838 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 42838 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 42838 times.
✗ Branch 5 not taken.
42838 (Item_field *)(cond_func->arguments()[1])->real_item(),
7543 equal_func, cond_func->arguments(), 1, usable_tables,
7544 sargables))
7545 return true;
7546 } else {
7547
2/4
✓ Branch 0 taken 414075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 414075 times.
✗ Branch 3 not taken.
414075 Item *real_item = cond_func->arguments()[1]->real_item();
7548
3/4
✓ Branch 0 taken 414075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22180 times.
✓ Branch 3 taken 391895 times.
414075 if (real_item->type() == Item::FUNC_ITEM) {
7549 22180 Item_func *func_item = down_cast<Item_func *>(real_item);
7550
3/4
✓ Branch 0 taken 22180 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 22109 times.
22180 if (func_item->functype() == Item_func::COLLATE_FUNC) {
7551
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 Item *key_item = func_item->key_item();
7552
3/4
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 50 times.
71 if (key_item->type() == Item::FIELD_ITEM) {
7553
3/6
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
21 if (add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7554 down_cast<Item_field *>(key_item),
7555 equal_func, cond_func->arguments(), 1,
7556 usable_tables, sargables))
7557 return true;
7558 }
7559 }
7560 }
7561 }
7562
7563 456913 break;
7564 }
7565 26622 case Item_func::OPTIMIZE_NULL:
7566 /* column_name IS [NOT] NULL */
7567
6/8
✓ Branch 0 taken 26622 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26622 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 25376 times.
✓ Branch 5 taken 1246 times.
✓ Branch 6 taken 25376 times.
✓ Branch 7 taken 1246 times.
51998 if (is_local_field(cond_func->arguments()[0]) &&
7568
2/4
✓ Branch 0 taken 25376 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25376 times.
✗ Branch 3 not taken.
25376 !cond_func->is_outer_reference()) {
7569
2/4
✓ Branch 0 taken 25376 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25376 times.
✗ Branch 3 not taken.
25376 Item *tmp = new Item_null;
7570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25376 times.
25376 if (tmp == nullptr) return true;
7571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25376 times.
25376 if (add_key_equal_fields(
7572 thd, key_fields, *and_level, cond_func,
7573
2/4
✓ Branch 0 taken 25376 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25376 times.
✗ Branch 3 not taken.
25376 (Item_field *)(cond_func->arguments()[0])->real_item(),
7574
2/4
✓ Branch 0 taken 25376 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25376 times.
✗ Branch 3 not taken.
25376 cond_func->functype() == Item_func::ISNULL_FUNC, &tmp, 1,
7575 usable_tables, sargables))
7576 return true;
7577 }
7578 26622 break;
7579 2889248 case Item_func::OPTIMIZE_EQUAL:
7580 2889248 Item_equal *item_equal = (Item_equal *)cond;
7581 2889248 Item *const_item = item_equal->get_const();
7582
2/2
✓ Branch 0 taken 926385 times.
✓ Branch 1 taken 1962857 times.
2889242 if (const_item) {
7583 /*
7584 For each field field1 from item_equal consider the equality
7585 field1=const_item as a condition allowing an index access of the table
7586 with field1 by the keys value of field1.
7587 */
7588
5/8
✓ Branch 0 taken 926419 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 926449 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2012990 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1086549 times.
✓ Branch 7 taken 926441 times.
2012968 for (Item_field &item : item_equal->get_fields()) {
7589
2/4
✓ Branch 0 taken 1086583 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1086583 times.
1086553 if (add_key_field(thd, key_fields, *and_level, cond_func, &item, true,
7590 &const_item, 1, usable_tables, sargables))
7591 return true;
7592 }
7593 } else {
7594 /*
7595 Consider all pairs of different fields included into item_equal.
7596 For each of them (field1, field1) consider the equality
7597 field1=field2 as a condition allowing an index access of the table
7598 with field1 by the keys value of field2.
7599 */
7600
5/8
✓ Branch 0 taken 1962856 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1962850 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5918139 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3955329 times.
✓ Branch 7 taken 1962810 times.
5918161 for (Item_field &outer : item_equal->get_fields()) {
7601
5/8
✓ Branch 0 taken 3955415 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3955392 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12764239 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8808935 times.
✓ Branch 7 taken 3955304 times.
12764270 for (Item_field &inner : item_equal->get_fields()) {
7602
3/4
✓ Branch 0 taken 8808865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4853535 times.
✓ Branch 3 taken 3955330 times.
8808929 if (!outer.field->eq(inner.field)) {
7603 4853535 Item *inner_ptr = &inner;
7604
2/4
✓ Branch 0 taken 4853558 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4853558 times.
4853535 if (add_key_field(thd, key_fields, *and_level, cond_func, &outer,
7605 true, &inner_ptr, 1, usable_tables, sargables))
7606 return true;
7607 }
7608 }
7609 }
7610 }
7611 2889251 break;
7612 }
7613 4684069 return false;
7614 }
7615
7616 /*
7617 Add all keys with uses 'field' for some keypart
7618 If field->and_level != and_level then only mark key_part as const_part
7619
7620 RETURN
7621 0 - OK
7622 1 - Out of memory.
7623 */
7624
7625 4467892 static bool add_key_part(Key_use_array *keyuse_array, Key_field *key_field) {
7626
3/4
✓ Branch 0 taken 4467916 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4467617 times.
✓ Branch 3 taken 299 times.
4467892 if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS)) {
7627 4467617 const Field *const field = key_field->item_field->field;
7628 4467617 TABLE_LIST *const tl = key_field->item_field->table_ref;
7629 4467617 TABLE *const table = tl->table;
7630
7631
2/2
✓ Branch 0 taken 17112641 times.
✓ Branch 1 taken 4467935 times.
21580576 for (uint key = 0; key < table->s->keys; key++) {
7632
2/2
✓ Branch 0 taken 6777 times.
✓ Branch 1 taken 17105907 times.
17112641 if (!(table->keys_in_use_for_query.is_set(key))) continue;
7633
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 17105501 times.
17105907 if (table->key_info[key].flags & (HA_FULLTEXT | HA_SPATIAL))
7634 406 continue; // ToDo: ft-keys in non-ft queries. SerG
7635
7636 17105501 uint key_parts = actual_key_parts(&table->key_info[key]);
7637
2/2
✓ Branch 0 taken 29191430 times.
✓ Branch 1 taken 17105776 times.
46297206 for (uint part = 0; part < key_parts; part++) {
7638
2/2
✓ Branch 0 taken 6590941 times.
✓ Branch 1 taken 22600828 times.
29191430 if (field->eq(table->key_info[key].key_part[part].field)) {
7639 const Key_use keyuse(tl, key_field->val,
7640 6590941 key_field->val->used_tables(), key, part,
7641 6590941 key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL,
7642 (key_part_map)1 << part,
7643 ~(ha_rows)0, // will be set in optimize_keyuse
7644 6590941 key_field->null_rejecting, key_field->cond_guard,
7645
1/2
✓ Branch 0 taken 6590798 times.
✗ Branch 1 not taken.
6590941 key_field->sj_pred_no);
7646
2/4
✓ Branch 0 taken 6590776 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6590776 times.
6590782 if (keyuse_array->push_back(keyuse))
7647 return true; /* purecov: inspected */
7648 }
7649 }
7650 }
7651 }
7652 4468210 return false;
7653 }
7654
7655 /**
7656 Function parses WHERE condition and add key_use for FT index
7657 into key_use array if suitable MATCH function is found.
7658 Condition should be a set of AND expression, OR is not supported.
7659 MATCH function should be a part of simple expression.
7660 Simple expression is MATCH only function or MATCH is a part of
7661 comparison expression ('>=' or '>' operations are supported).
7662 It also sets FT_HINTS values(op_type, op_value).
7663
7664 @param keyuse_array Key_use array
7665 @param cond WHERE condition
7666 @param usable_tables usable tables
7667 @param simple_match_expr true if this is the first call false otherwise.
7668 if MATCH function is found at first call it means
7669 that MATCH is simple expression, otherwise, in case
7670 of AND/OR condition this parameter will be false.
7671
7672 @retval
7673 true if FT key was added to Key_use array
7674 @retval
7675 false if no key was added to Key_use array
7676
7677 */
7678
7679 2560 static bool add_ft_keys(Key_use_array *keyuse_array, Item *cond,
7680 table_map usable_tables, bool simple_match_expr) {
7681 2560 Item_func_match *cond_func = nullptr;
7682
7683
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2552 times.
2560 if (!cond) return false;
7684
7685
2/4
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2552 times.
2552 assert(cond->is_bool_func());
7686
7687
3/4
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2405 times.
✓ Branch 3 taken 147 times.
2552 if (cond->type() == Item::FUNC_ITEM) {
7688 2405 Item_func *func = down_cast<Item_func *>(cond);
7689
1/2
✓ Branch 0 taken 2405 times.
✗ Branch 1 not taken.
2405 Item_func::Functype functype = func->functype();
7690
2/2
✓ Branch 0 taken 2181 times.
✓ Branch 1 taken 224 times.
2405 if (functype == Item_func::MATCH_FUNC) {
7691
1/2
✓ Branch 0 taken 2181 times.
✗ Branch 1 not taken.
2181 func = down_cast<Item_func *>(func->arguments()[0]);
7692
1/2
✓ Branch 0 taken 2181 times.
✗ Branch 1 not taken.
2181 functype = func->functype();
7693 }
7694 2405 enum ft_operation op_type = FT_OP_NO;
7695 2405 double op_value = 0.0;
7696
2/2
✓ Branch 0 taken 2181 times.
✓ Branch 1 taken 224 times.
2405 if (functype == Item_func::FT_FUNC) {
7697
1/2
✓ Branch 0 taken 2181 times.
✗ Branch 1 not taken.
2181 cond_func = down_cast<Item_func_match *>(func)->get_master();
7698 2181 cond_func->set_hints_op(op_type, op_value);
7699
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 97 times.
224 } else if (func->arg_count == 2) {
7700
1/2
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
127 Item *arg0 = func->arguments()[0];
7701
1/2
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
127 Item *arg1 = func->arguments()[1];
7702
10/12
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 77 times.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 35 times.
✓ Branch 7 taken 15 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 31 times.
✓ Branch 10 taken 33 times.
✓ Branch 11 taken 94 times.
162 if (arg1->const_item() && is_function_of_type(arg0, Item_func::FT_FUNC) &&
7703 4 ((functype == Item_func::GE_FUNC &&
7704
5/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 31 times.
✓ Branch 5 taken 2 times.
35 (op_value = arg1->val_real()) > 0) ||
7705 31 (functype == Item_func::GT_FUNC &&
7706
2/4
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
31 (op_value = arg1->val_real()) >= 0))) {
7707
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 cond_func = down_cast<Item_func_match *>(arg0)->get_master();
7708
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 31 times.
33 if (functype == Item_func::GE_FUNC)
7709 2 op_type = FT_OP_GE;
7710
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 else if (functype == Item_func::GT_FUNC)
7711 31 op_type = FT_OP_GT;
7712 33 cond_func->set_hints_op(op_type, op_value);
7713
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 } else if (arg0->const_item() &&
7714
9/10
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 55 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 8 times.
✓ Branch 9 taken 86 times.
104 is_function_of_type(arg1, Item_func::FT_FUNC) &&
7715 6 ((functype == Item_func::LE_FUNC &&
7716
5/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 2 times.
10 (op_value = arg0->val_real()) > 0) ||
7717 4 (functype == Item_func::LT_FUNC &&
7718
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 (op_value = arg0->val_real()) >= 0))) {
7719
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 cond_func = down_cast<Item_func_match *>(arg1)->get_master();
7720
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (functype == Item_func::LE_FUNC)
7721 4 op_type = FT_OP_GE;
7722
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 else if (functype == Item_func::LT_FUNC)
7723 4 op_type = FT_OP_GT;
7724 8 cond_func->set_hints_op(op_type, op_value);
7725 }
7726 }
7727
2/4
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 147 times.
✗ Branch 3 not taken.
147 } else if (cond->type() == Item::COND_ITEM) {
7728
1/2
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
147 List_iterator_fast<Item> li(*down_cast<Item_cond *>(cond)->argument_list());
7729
7730
3/4
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 142 times.
✓ Branch 3 taken 5 times.
147 if (down_cast<Item_cond *>(cond)->functype() == Item_func::COND_AND_FUNC) {
7731 Item *item;
7732
2/2
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 142 times.
448 while ((item = li++))
7733
2/4
✓ Branch 0 taken 306 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 306 times.
306 if (add_ft_keys(keyuse_array, item, usable_tables, false)) return true;
7734 }
7735 }
7736
7737
6/6
✓ Branch 0 taken 2222 times.
✓ Branch 1 taken 330 times.
✓ Branch 2 taken 2201 times.
✓ Branch 3 taken 21 times.
✓ Branch 4 taken 356 times.
✓ Branch 5 taken 2196 times.
4753 if (!cond_func || cond_func->key == NO_SUCH_KEY ||
7738
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2196 times.
2201 !(usable_tables & cond_func->table_ref->map()))
7739 356 return false;
7740
7741 2196 TABLE_LIST *tbl = cond_func->table_ref;
7742
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2194 times.
2196 if (!tbl->table->keys_in_use_for_query.is_set(cond_func->key)) return false;
7743
7744 2194 cond_func->set_simple_expression(simple_match_expr);
7745
7746 4388 const Key_use keyuse(tbl, cond_func, cond_func->key_item()->used_tables(),
7747 cond_func->key, FT_KEYPART,
7748 0, // optimize
7749 0, // keypart_map
7750 ~(ha_rows)0, // ref_table_rows
7751 false, // null_rejecting
7752 nullptr, // cond_guard
7753
1/2
✓ Branch 0 taken 2194 times.
✗ Branch 1 not taken.
2194 UINT_MAX); // sj_pred_no
7754 2194 tbl->table->reginfo.join_tab->keys().set_bit(cond_func->key);
7755
1/2
✓ Branch 0 taken 2194 times.
✗ Branch 1 not taken.
2194 return keyuse_array->push_back(keyuse);
7756 }
7757
7758 /**
7759 Compares two keyuse elements.
7760
7761 @param a first Key_use element
7762 @param b second Key_use element
7763
7764 Compare Key_use elements so that they are sorted as follows:
7765 -# By table.
7766 -# By key for each table.
7767 -# By keypart for each key.
7768 -# Const values.
7769 -# Ref_or_null.
7770
7771 @retval true If a < b.
7772 @retval false If a >= b.
7773 */
7774 31796346 static bool sort_keyuse(const Key_use &a, const Key_use &b) {
7775
2/2
✓ Branch 0 taken 20214477 times.
✓ Branch 1 taken 11582130 times.
31796346 if (a.table_ref->tableno() != b.table_ref->tableno())
7776 20214477 return a.table_ref->tableno() < b.table_ref->tableno();
7777
2/2
✓ Branch 0 taken 7992176 times.
✓ Branch 1 taken 3589954 times.
11582130 if (a.key != b.key) return a.key < b.key;
7778
2/2
✓ Branch 0 taken 699147 times.
✓ Branch 1 taken 2890807 times.
3589954 if (a.keypart != b.keypart) return a.keypart < b.keypart;
7779 // Place const values before other ones
7780 2890807 bool a_const = a.used_tables & ~OUTER_REF_TABLE_BIT;
7781 2890807 bool b_const = b.used_tables & ~OUTER_REF_TABLE_BIT;
7782
2/2
✓ Branch 0 taken 654 times.
✓ Branch 1 taken 2890153 times.
2890807 if (a_const != b_const) return b_const;
7783 /* Place rows that are not 'OPTIMIZE_REF_OR_NULL' first */
7784 2890153 return (a.optimize & KEY_OPTIMIZE_REF_OR_NULL) <
7785 2890153 (b.optimize & KEY_OPTIMIZE_REF_OR_NULL);
7786 }
7787
7788 /*
7789 Add to Key_field array all 'ref' access candidates within nested join.
7790
7791 This function populates Key_field array with entries generated from the
7792 ON condition of the given nested join, and does the same for nested joins
7793 contained within this nested join.
7794
7795 @param thd session context
7796 @param[in] nested_join_table Nested join pseudo-table to process
7797 @param[in,out] end End of the key field array
7798 @param[in,out] and_level And-level
7799 @param[in,out] sargables Array of found sargable candidates
7800
7801 @returns false if success, true if error
7802
7803 @note
7804 We can add accesses to the tables that are direct children of this nested
7805 join (1), and are not inner tables w.r.t their neighbours (2).
7806
7807 Example for #1 (outer brackets pair denotes nested join this function is
7808 invoked for):
7809 @code
7810 ... LEFT JOIN (t1 LEFT JOIN (t2 ... ) ) ON cond
7811 @endcode
7812 Example for #2:
7813 @code
7814 ... LEFT JOIN (t1 LEFT JOIN t2 ) ON cond
7815 @endcode
7816 In examples 1-2 for condition cond, we can add 'ref' access candidates to
7817 t1 only.
7818 Example #3:
7819 @code
7820 ... LEFT JOIN (t1, t2 LEFT JOIN t3 ON inner_cond) ON cond
7821 @endcode
7822 Here we can add 'ref' access candidates for t1 and t2, but not for t3.
7823 */
7824
7825 24256 static bool add_key_fields_for_nj(THD *thd, JOIN *join,
7826 TABLE_LIST *nested_join_table,
7827 Key_field **end, uint *and_level,
7828 SARGABLE_PARAM **sargables) {
7829 24256 mem_root_deque<TABLE_LIST *> &join_list =
7830 24256 nested_join_table->nested_join->join_list;
7831
1/2
✓ Branch 0 taken 24256 times.
✗ Branch 1 not taken.
24256 auto li = join_list.begin();
7832
1/2
✓ Branch 0 taken 24256 times.
✗ Branch 1 not taken.
24256 auto li_end = join_list.end();
7833
1/2
✓ Branch 0 taken 24256 times.
✗ Branch 1 not taken.
24256 auto li2 = join_list.begin();
7834
1/2
✓ Branch 0 taken 24256 times.
✗ Branch 1 not taken.
24256 auto li2_end = join_list.end();
7835 24256 bool have_another = false;
7836 24256 table_map tables = 0;
7837 TABLE_LIST *table;
7838
7839
9/12
✓ Branch 0 taken 71755 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46549 times.
✓ Branch 3 taken 25206 times.
✓ Branch 4 taken 46549 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 46549 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 25206 times.
✓ Branch 9 taken 46549 times.
✓ Branch 10 taken 950 times.
✓ Branch 11 taken 24256 times.
72705 while ((table = (li != li_end) ? *li++ : nullptr) ||
7840
3/6
✓ Branch 0 taken 950 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 950 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 950 times.
✗ Branch 5 not taken.
950 (have_another && li2 != join_list.end() &&
7841 950 (li = li2, li_end = li2_end, have_another = false,
7842
7/12
✓ Branch 0 taken 950 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 950 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 950 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 950 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 950 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 47499 times.
✓ Branch 11 taken 24256 times.
72705 (li != li_end) && (table = *li++)))) {
7843
2/2
✓ Branch 0 taken 1347 times.
✓ Branch 1 taken 46152 times.
47499 if (table->nested_join) {
7844
2/2
✓ Branch 0 taken 950 times.
✓ Branch 1 taken 397 times.
1347 if (!table->join_cond_optim()) {
7845 /* It's a semi-join nest. Walk into it as if it wasn't a nest */
7846 950 have_another = true;
7847 950 li2 = li;
7848 950 li2_end = li_end;
7849
1/2
✓ Branch 0 taken 950 times.
✗ Branch 1 not taken.
950 li = table->nested_join->join_list.begin();
7850
1/2
✓ Branch 0 taken 950 times.
✗ Branch 1 not taken.
950 li_end = table->nested_join->join_list.end();
7851 } else {
7852
2/4
✓ Branch 0 taken 397 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 397 times.
397 if (add_key_fields_for_nj(thd, join, table, end, and_level, sargables))
7853 return true;
7854 }
7855
2/2
✓ Branch 0 taken 40157 times.
✓ Branch 1 taken 5995 times.
46152 } else if (!table->join_cond_optim())
7856 40157 tables |= table->map();
7857 }
7858
2/2
✓ Branch 0 taken 3477 times.
✓ Branch 1 taken 20779 times.
24256 if (nested_join_table->join_cond_optim()) {
7859
2/4
✓ Branch 0 taken 3477 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3477 times.
3477 if (add_key_fields(thd, join, end, and_level,
7860 nested_join_table->join_cond_optim(), tables, sargables))
7861 return true;
7862 }
7863 24256 return false;
7864 }
7865
7866 /// @} (end of group RefOptimizerModule)
7867
7868 /**
7869 Check for the presence of AGGFN(DISTINCT a) queries that may be subject
7870 to loose index scan.
7871
7872
7873 Check if the query is a subject to AGGFN(DISTINCT) using loose index scan
7874 (GroupIndexSkipScanIterator).
7875 Optionally (if out_args is supplied) will push the arguments of
7876 AGGFN(DISTINCT) to the list
7877
7878 Check for every COUNT(DISTINCT), AVG(DISTINCT) or
7879 SUM(DISTINCT). These can be resolved by Loose Index Scan as long
7880 as all the aggregate distinct functions refer to the same
7881 fields. Thus:
7882
7883 SELECT AGGFN(DISTINCT a, b), AGGFN(DISTINCT b, a)... => can use LIS
7884 SELECT AGGFN(DISTINCT a), AGGFN(DISTINCT a) ... => can use LIS
7885 SELECT AGGFN(DISTINCT a, b), AGGFN(DISTINCT a) ... => cannot use LIS
7886 SELECT AGGFN(DISTINCT a), AGGFN(DISTINCT b) ... => cannot use LIS
7887 etc.
7888
7889 @param join the join to check
7890 @param[out] out_args Collect the arguments of the aggregate functions
7891 to a list. We don't worry about duplicates as
7892 these will be sorted out later in
7893 get_best_group_min_max.
7894
7895 @return does the query qualify for indexed AGGFN(DISTINCT)
7896 @retval true it does
7897 @retval false AGGFN(DISTINCT) must apply distinct in it.
7898 */
7899
7900 2563780 bool is_indexed_agg_distinct(JOIN *join,
7901 mem_root_deque<Item_field *> *out_args) {
7902 Item_sum **sum_item_ptr;
7903 2563780 bool result = false;
7904
1/2
✓ Branch 0 taken 2563886 times.
✗ Branch 1 not taken.
2563780 Field_map first_aggdistinct_fields;
7905
7906
2/2
✓ Branch 0 taken 2125326 times.
✓ Branch 1 taken 438560 times.
2563886 if (join->primary_tables > 1 || /* reference more than 1 table */
7907
2/2
✓ Branch 0 taken 2122457 times.
✓ Branch 1 taken 2869 times.
2125326 join->select_distinct || /* or a DISTINCT */
7908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2122457 times.
2122457 join->query_block->olap == ROLLUP_TYPE) /* Check (B3) for ROLLUP */
7909 441429 return false;
7910
7911
2/4
✓ Branch 0 taken 2122457 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2122457 times.
2122457 if (join->make_sum_func_list(*join->fields, true)) return false;
7912
7913
2/2
✓ Branch 0 taken 670704 times.
✓ Branch 1 taken 1483496 times.
2154200 for (sum_item_ptr = join->sum_funcs; *sum_item_ptr; sum_item_ptr++) {
7914 670704 Item_sum *sum_item = *sum_item_ptr;
7915
1/2
✓ Branch 0 taken 670704 times.
✗ Branch 1 not taken.
670704 Field_map cur_aggdistinct_fields;
7916 Item *expr;
7917 /* aggregate is not AGGFN(DISTINCT) or more than 1 argument to it */
7918
5/6
✓ Branch 0 taken 670704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30053 times.
✓ Branch 3 taken 1346 times.
✓ Branch 4 taken 539 times.
✓ Branch 5 taken 638766 times.
670704 switch (sum_item->sum_func()) {
7919 30053 case Item_sum::MIN_FUNC:
7920 case Item_sum::MAX_FUNC:
7921 30053 continue;
7922 1346 case Item_sum::COUNT_DISTINCT_FUNC:
7923 1346 break;
7924 539 case Item_sum::AVG_DISTINCT_FUNC:
7925 case Item_sum::SUM_DISTINCT_FUNC:
7926
2/4
✓ Branch 0 taken 539 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✗ Branch 3 not taken.
539 if (sum_item->argument_count() == 1) break;
7927 [[fallthrough]];
7928 default:
7929 638961 return false;
7930 }
7931
7932
3/4
✓ Branch 0 taken 3860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2134 times.
✓ Branch 3 taken 1726 times.
3860 for (uint i = 0; i < sum_item->argument_count(); i++) {
7933
1/2
✓ Branch 0 taken 2134 times.
✗ Branch 1 not taken.
2134 expr = sum_item->get_arg(i);
7934 /* The AGGFN(DISTINCT) arg is not an attribute? */
7935
4/6
✓ Branch 0 taken 2134 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2134 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 159 times.
✓ Branch 5 taken 1975 times.
2134 if (expr->real_item()->type() != Item::FIELD_ITEM) return false;
7936
7937
1/2
✓ Branch 0 taken 1975 times.
✗ Branch 1 not taken.
1975 Item_field *item = static_cast<Item_field *>(expr->real_item());
7938
3/4
✓ Branch 0 taken 1097 times.
✓ Branch 1 taken 878 times.
✓ Branch 2 taken 1097 times.
✗ Branch 3 not taken.
1975 if (out_args) out_args->push_back(item);
7939
7940 1975 cur_aggdistinct_fields.set_bit(item->field->field_index());
7941 1975 result = true;
7942 }
7943 /*
7944 If there are multiple aggregate functions, make sure that they all
7945 refer to exactly the same set of columns.
7946 */
7947
3/4
✓ Branch 0 taken 1726 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1453 times.
✓ Branch 3 taken 273 times.
1726 if (first_aggdistinct_fields.is_clear_all())
7948
1/2
✓ Branch 0 taken 1453 times.
✗ Branch 1 not taken.
1453 first_aggdistinct_fields.merge(cur_aggdistinct_fields);
7949
3/4
✓ Branch 0 taken 273 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 237 times.
273 else if (first_aggdistinct_fields != cur_aggdistinct_fields)
7950 36 return false;
7951 }
7952
7953 1483496 return result;
7954 }
7955
7956 /**
7957 Print keys that were appended to join_tab->const_keys because they
7958 can be used for GROUP BY or DISTINCT to the optimizer trace.
7959
7960 @param trace The optimizer trace context we're adding info to
7961 @param join_tab The table the indexes cover
7962 @param new_keys The keys that are considered useful because they can
7963 be used for GROUP BY or DISTINCT
7964 @param cause Zero-terminated string with reason for adding indexes
7965 to const_keys
7966
7967 @see add_group_and_distinct_keys()
7968 */
7969 12507 static void trace_indexes_added_group_distinct(Opt_trace_context *trace,
7970 const JOIN_TAB *join_tab,
7971 const Key_map new_keys,
7972 const char *cause) {
7973
2/2
✓ Branch 0 taken 12424 times.
✓ Branch 1 taken 83 times.
12507 if (likely(!trace->is_started())) return;
7974
7975 83 KEY *key_info = join_tab->table()->key_info;
7976 83 Key_map existing_keys = join_tab->const_keys;
7977 83 uint nbrkeys = join_tab->table()->s->keys;
7978
7979
1/2
✓ Branch 0 taken 83 times.
✗ Branch 1 not taken.
83 Opt_trace_object trace_summary(trace, "const_keys_added");
7980 {
7981
1/2
✓ Branch 0 taken 83 times.
✗ Branch 1 not taken.
83 Opt_trace_array trace_key(trace, "keys");
7982
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 83 times.
208 for (uint j = 0; j < nbrkeys; j++)
7983
6/6
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 110 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 110 times.
✓ Branch 5 taken 15 times.
125 if (new_keys.is_set(j) && !existing_keys.is_set(j))
7984
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
110 trace_key.add_utf8(key_info[j].name);
7985 83 }
7986
1/2
✓ Branch 0 taken 83 times.
✗ Branch 1 not taken.
83 trace_summary.add_alnum("cause", cause);
7987 83 }
7988
7989 /**
7990 Discover the indexes that might be used for GROUP BY or DISTINCT queries or
7991 indexes that might be used for SKIP SCAN.
7992
7993 If the query has a GROUP BY clause, find all indexes that contain
7994 all GROUP BY fields, and add those indexes to join_tab->const_keys
7995 and join_tab->keys.
7996
7997 If the query has a DISTINCT clause, find all indexes that contain
7998 all SELECT fields, and add those indexes to join_tab->const_keys and
7999 join_tab->keys. This allows later on such queries to be processed by
8000 a GroupIndexSkipScanIterator.
8001
8002 If the query does not have GROUP BY clause or any aggregate function
8003 the function collects possible keys to use for skip scan access.
8004
8005 Note that indexes that are not usable for resolving GROUP
8006 BY/DISTINCT may also be added in some corner cases. For example, an
8007 index covering 'a' and 'b' is not usable for the following query but
8008 is still added: "SELECT DISTINCT a+b FROM t1". This is not a big
8009 issue because a) although the optimizer will consider using the
8010 index, it will not chose it (so minor calculation cost added but not
8011 wrong result) and b) it applies only to corner cases.
8012
8013 @param join the current join
8014 @param join_tab joined table
8015 */
8016
8017 3820856 static void add_loose_index_scan_and_skip_scan_keys(JOIN *join,
8018 JOIN_TAB *join_tab) {
8019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3820898 times.
3820856 assert(join_tab->const_keys.is_subset(join_tab->keys()));
8020
8021 3820898 mem_root_deque<Item_field *> indexed_fields(join->thd->mem_root);
8022 ORDER *cur_group;
8023 const char *cause;
8024
8025 /* Find the indexes that might be used for skip scan queries. */
8026
1/2
✓ Branch 0 taken 3820853 times.
✗ Branch 1 not taken.
3820840 if (hint_table_state(join->thd, join_tab->table_ref, SKIP_SCAN_HINT_ENUM,
8027 3817159 OPTIMIZER_SKIP_SCAN) &&
8028
6/6
✓ Branch 0 taken 3171714 times.
✓ Branch 1 taken 645445 times.
✓ Branch 2 taken 679114 times.
✓ Branch 3 taken 2492600 times.
✓ Branch 4 taken 664651 times.
✓ Branch 5 taken 14463 times.
4496273 join->where_cond && join->primary_tables == 1 &&
8029 679114 join->group_list.empty() &&
8030
7/8
✓ Branch 0 taken 3817159 times.
✓ Branch 1 taken 3694 times.
✓ Branch 2 taken 664679 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 664525 times.
✓ Branch 5 taken 154 times.
✓ Branch 6 taken 662890 times.
✓ Branch 7 taken 3157991 times.
8302537 !is_indexed_agg_distinct(join, &indexed_fields) &&
8031
2/2
✓ Branch 0 taken 662890 times.
✓ Branch 1 taken 1635 times.
664525 !join->select_distinct) {
8032
1/2
✓ Branch 0 taken 662890 times.
✗ Branch 1 not taken.
662890 join->where_cond->walk(&Item::collect_item_field_processor,
8033 enum_walk::POSTFIX, (uchar *)&indexed_fields);
8034
1/2
✓ Branch 0 taken 662890 times.
✗ Branch 1 not taken.
662890 Key_map possible_keys;
8035 662890 possible_keys.set_all();
8036 662890 join_tab->skip_scan_keys.clear_all();
8037
7/12
✓ Branch 0 taken 662890 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 662890 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 910668 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 906464 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1569354 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 910668 times.
✓ Branch 11 taken 658686 times.
1569354 for (Item_field *cur_item : indexed_fields) {
8038
3/4
✓ Branch 0 taken 910668 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4204 times.
✓ Branch 3 taken 906464 times.
910668 if (cur_item->used_tables() != join_tab->table_ref->map()) return;
8039 906464 possible_keys.intersect(cur_item->field->part_of_key);
8040 }
8041 658686 join_tab->skip_scan_keys.merge(possible_keys);
8042 658686 cause = "skip_scan";
8043 658686 return;
8044 }
8045
8046
2/2
✓ Branch 0 taken 32964 times.
✓ Branch 1 taken 3125050 times.
3157991 if (!join->group_list.empty()) {
8047 /* Collect all query fields referenced in the GROUP clause. */
8048
2/2
✓ Branch 0 taken 57202 times.
✓ Branch 1 taken 32964 times.
90166 for (cur_group = join->group_list.order; cur_group;
8049 57202 cur_group = cur_group->next)
8050 57202 (*cur_group->item)
8051
1/2
✓ Branch 0 taken 57202 times.
✗ Branch 1 not taken.
57202 ->walk(&Item::collect_item_field_processor, enum_walk::POSTFIX,
8052 (uchar *)&indexed_fields);
8053 32964 cause = "group_by";
8054
2/2
✓ Branch 0 taken 7919 times.
✓ Branch 1 taken 3117131 times.
3125050 } else if (join->select_distinct) {
8055 /* Collect all query fields referenced in the SELECT clause. */
8056
8/14
✓ Branch 0 taken 7919 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7919 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7919 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 28837 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 28837 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 36756 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 28837 times.
✓ Branch 13 taken 7919 times.
36756 for (Item *item : VisibleFields(*join->fields)) {
8057
1/2
✓ Branch 0 taken 28837 times.
✗ Branch 1 not taken.
28837 item->walk(&Item::collect_item_field_processor, enum_walk::POSTFIX,
8058 (uchar *)&indexed_fields);
8059 }
8060 7919 cause = "distinct";
8061
4/4
✓ Branch 0 taken 292773 times.
✓ Branch 1 taken 2824358 times.
✓ Branch 2 taken 324 times.
✓ Branch 3 taken 3116807 times.
3409904 } else if (join->tmp_table_param.sum_func_count &&
8062
3/4
✓ Branch 0 taken 292773 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 324 times.
✓ Branch 3 taken 292449 times.
292773 is_indexed_agg_distinct(join, &indexed_fields)) {
8063 /*
8064 SELECT list with AGGFN(distinct col). The query qualifies for
8065 loose index scan, and is_indexed_agg_distinct() has already
8066 collected all referenced fields into indexed_fields.
8067 */
8068 324 join->streaming_aggregation = true;
8069 324 cause = "indexed_distinct_aggregate";
8070 } else
8071 3116807 return;
8072
8073
3/4
✓ Branch 0 taken 41207 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 40892 times.
41207 if (indexed_fields.empty()) return;
8074
8075 40892 Key_map possible_keys = join_tab->table()->keys_in_use_for_query;
8076 40892 possible_keys.merge(join_tab->table()->keys_in_use_for_group_by);
8077
8078 /* Intersect the keys of all group fields. */
8079
7/12
✓ Branch 0 taken 40892 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40892 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49609 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 34959 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 75851 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 49609 times.
✓ Branch 11 taken 26242 times.
75851 for (Item_field *cur_item : indexed_fields) {
8080
3/4
✓ Branch 0 taken 49609 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14650 times.
✓ Branch 3 taken 34959 times.
49609 if (cur_item->used_tables() != join_tab->table_ref->map()) {
8081 /*
8082 Doing GROUP BY or DISTINCT on a field in another table so no
8083 index in this table is usable
8084 */
8085 14650 return;
8086 } else
8087 34959 possible_keys.intersect(cur_item->field->part_of_key);
8088 }
8089
8090 /*
8091 At this point, possible_keys has key bits set only for usable
8092 indexes because indexed_fields is non-empty and if any of the
8093 fields belong to a different table the function would exit in the
8094 loop above.
8095 */
8096
8097
4/4
✓ Branch 0 taken 14026 times.
✓ Branch 1 taken 12216 times.
✓ Branch 2 taken 12507 times.
✓ Branch 3 taken 13735 times.
40268 if (!possible_keys.is_clear_all() &&
8098
2/2
✓ Branch 0 taken 12507 times.
✓ Branch 1 taken 1519 times.
14026 !possible_keys.is_subset(join_tab->const_keys)) {
8099
1/2
✓ Branch 0 taken 12507 times.
✗ Branch 1 not taken.
12507 trace_indexes_added_group_distinct(&join->thd->opt_trace, join_tab,
8100 possible_keys, cause);
8101 12507 join_tab->const_keys.merge(possible_keys);
8102 12507 join_tab->keys().merge(possible_keys);
8103 }
8104
8105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26242 times.
26242 assert(join_tab->const_keys.is_subset(join_tab->keys()));
8106
2/2
✓ Branch 0 taken 26242 times.
✓ Branch 1 taken 3794610 times.
3820904 }
8107
8108 /**
8109 Update keyuse array with all possible keys we can use to fetch rows.
8110
8111 @param thd session context
8112 @param[out] keyuse Put here ordered array of Key_use structures
8113 @param join_tab Array in table number order
8114 @param tables Number of tables in join
8115 @param cond WHERE condition (note that the function analyzes
8116 join_tab[i]->join_cond() too)
8117 @param normal_tables Tables not inner w.r.t some outer join (ones
8118 for which we can make ref access based the WHERE
8119 clause)
8120 @param query_block current SELECT
8121 @param[out] sargables Array of found sargable candidates
8122
8123 @returns false if success, true if error
8124 */
8125
8126 1240771 static bool update_ref_and_keys(THD *thd, Key_use_array *keyuse,
8127 JOIN_TAB *join_tab, uint tables, Item *cond,
8128 table_map normal_tables,
8129 Query_block *query_block,
8130 SARGABLE_PARAM **sargables) {
8131
4/6
✓ Branch 0 taken 1235118 times.
✓ Branch 1 taken 5653 times.
✓ Branch 2 taken 1235175 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1235175 times.
1240771 assert(cond == nullptr || cond->is_bool_func());
8132 uint and_level, i;
8133 Key_field *key_fields, *end, *field;
8134 size_t sz;
8135 1240828 uint m = max(query_block->max_equal_elems, 1U);
8136 1240827 JOIN *const join = query_block->join;
8137 /*
8138 We use the same piece of memory to store both Key_field
8139 and SARGABLE_PARAM structure.
8140 Key_field values are placed at the beginning this memory
8141 while SARGABLE_PARAM values are put at the end.
8142 All predicates that are used to fill arrays of Key_field
8143 and SARGABLE_PARAM structures have at most 2 arguments
8144 except BETWEEN predicates that have 3 arguments and
8145 IN predicates.
8146 This any predicate if it's not BETWEEN/IN can be used
8147 directly to fill at most 2 array elements, either of Key_field
8148 or SARGABLE_PARAM type. For a BETWEEN predicate 3 elements
8149 can be filled as this predicate is considered as
8150 saragable with respect to each of its argument.
8151 An IN predicate can require at most 1 element as currently
8152 it is considered as sargable only for its first argument.
8153 Multiple equality can add elements that are filled after
8154 substitution of field arguments by equal fields. There
8155 can be not more than query_block->max_equal_elems such
8156 substitutions.
8157 */
8158 1240827 sz = max(sizeof(Key_field), sizeof(SARGABLE_PARAM)) *
8159 1240807 (((query_block->cond_count + 1) * 2 + query_block->between_count) * m +
8160 1);
8161
2/4
✓ Branch 0 taken 1240822 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1240822 times.
1240807 if (!(key_fields = (Key_field *)thd->alloc(sz)))
8162 return true; /* purecov: inspected */
8163 1240822 and_level = 0;
8164 1240822 field = end = key_fields;
8165 1240822 *sargables = (SARGABLE_PARAM *)key_fields +
8166 1240822 (sz - sizeof((*sargables)[0].field)) / sizeof(SARGABLE_PARAM);
8167 /* set a barrier for the array of SARGABLE_PARAM */
8168 1240822 (*sargables)[0].field = nullptr;
8169
8170
2/2
✓ Branch 0 taken 1235182 times.
✓ Branch 1 taken 5640 times.
1240822 if (cond) {
8171
2/4
✓ Branch 0 taken 1235191 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1235191 times.
1235182 if (add_key_fields(thd, join, &end, &and_level, cond, normal_tables,
8172 sargables))
8173 return true;
8174
8175 // The relevant secondary engines don't support antijoin, so don't enable
8176 // this optimization for them.
8177
2/2
✓ Branch 0 taken 1235072 times.
✓ Branch 1 taken 119 times.
1235191 if (thd->secondary_engine_optimization() !=
8178 Secondary_engine_optimization::SECONDARY) {
8179
2/2
✓ Branch 0 taken 3784092 times.
✓ Branch 1 taken 1235054 times.
5019146 for (Key_field *fld = field; fld != end; fld++) {
8180 /* Mark that we can optimize LEFT JOIN */
8181
5/6
✓ Branch 0 taken 3784074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3099 times.
✓ Branch 3 taken 3780975 times.
✓ Branch 4 taken 471 times.
✓ Branch 5 taken 3783603 times.
3787191 if (fld->val->type() == Item::NULL_ITEM &&
8182
2/2
✓ Branch 0 taken 471 times.
✓ Branch 1 taken 2628 times.
3099 !fld->item_field->field->is_nullable()) {
8183 /*
8184 Example:
8185 SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.a IS NULL;
8186 this just wants rows of t1 where t1.a does not exist in t2.
8187 */
8188 471 fld->item_field->field->table->reginfo.not_exists_optimize = true;
8189 }
8190 }
8191 }
8192 }
8193
8194
2/2
✓ Branch 0 taken 3310873 times.
✓ Branch 1 taken 1240849 times.
4551722 for (i = 0; i < tables; i++) {
8195 /*
8196 Block the creation of keys for inner tables of outer joins.
8197 Here only the outer joins that can not be converted to
8198 inner joins are left and all nests that can be eliminated
8199 are flattened.
8200 In the future when we introduce conditional accesses
8201 for inner tables in outer joins these keys will be taken
8202 into account as well.
8203 */
8204
2/2
✓ Branch 0 taken 526892 times.
✓ Branch 1 taken 2783988 times.
3310873 if (join_tab[i].join_cond()) {
8205
2/4
✓ Branch 0 taken 526921 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 526921 times.
526902 if (add_key_fields(thd, join, &end, &and_level, join_tab[i].join_cond(),
8206 526892 join_tab[i].table_ref->map(), sargables))
8207 return true;
8208 }
8209 }
8210
8211 /* Process ON conditions for the nested joins */
8212
7/12
✓ Branch 0 taken 1240829 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1240851 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3288669 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3288673 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4529514 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3288669 times.
✓ Branch 11 taken 1240845 times.
4529518 for (TABLE_LIST *tl : query_block->top_join_list) {
8213
3/4
✓ Branch 0 taken 23859 times.
✓ Branch 1 taken 3264810 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3288669 times.
3312528 if (tl->nested_join &&
8214
2/4
✓ Branch 0 taken 23859 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 23859 times.
23859 add_key_fields_for_nj(thd, join, tl, &end, &and_level, sargables))
8215 return true;
8216 }
8217
8218 /* Generate keys descriptions for derived tables */
8219
2/2
✓ Branch 0 taken 2413 times.
✓ Branch 1 taken 1238432 times.
1240845 if (query_block->materialized_derived_table_count) {
8220
2/4
✓ Branch 0 taken 2413 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2413 times.
2413 if (join->generate_derived_keys()) return true;
8221 }
8222 /* fill keyuse with found key parts */
8223
2/2
✓ Branch 0 taken 4462977 times.
✓ Branch 1 taken 1240850 times.
5703827 for (; field != end; field++) {
8224
2/4
✓ Branch 0 taken 4462982 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4462982 times.
4462977 if (add_key_part(keyuse, field)) return true;
8225 }
8226
8227
2/2
✓ Branch 0 taken 2254 times.
✓ Branch 1 taken 1238596 times.
1240850 if (query_block->ftfunc_list->elements) {
8228
2/4
✓ Branch 0 taken 2254 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2254 times.
2254 if (add_ft_keys(keyuse, cond, normal_tables, true)) return true;
8229 }
8230
8231 /*
8232 Sort the array of possible keys and remove the following key parts:
8233 - ref if there is a keypart which is a ref and a const.
8234 (e.g. if there is a key(a,b) and the clause is a=3 and b=7 and b=t2.d,
8235 then we skip the key part corresponding to b=t2.d)
8236 - keyparts without previous keyparts
8237 (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is
8238 used in the query, we drop the partial key parts from consideration).
8239 Special treatment for ft-keys.
8240 */
8241
3/4
✓ Branch 0 taken 1240830 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 591892 times.
✓ Branch 3 taken 648938 times.
1240850 if (!keyuse->empty()) {
8242 Key_use *save_pos, *use;
8243
8244
1/2
✓ Branch 0 taken 591887 times.
✗ Branch 1 not taken.
591892 std::sort(keyuse->begin(), keyuse->begin() + keyuse->size(), sort_keyuse);
8245
8246 const Key_use key_end(nullptr, nullptr, 0, 0, 0, 0, 0, 0, false, nullptr,
8247 591887 0);
8248
2/4
✓ Branch 0 taken 591861 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 591861 times.
591888 if (keyuse->push_back(key_end)) // added for easy testing
8249 return true;
8250
8251 591861 use = save_pos = keyuse->begin();
8252 591881 const Key_use *prev = &key_end;
8253 591881 bool found_eq_constant = false;
8254
2/2
✓ Branch 0 taken 6588123 times.
✓ Branch 1 taken 591882 times.
7180050 for (i = 0; i < keyuse->size() - 1; i++, use++) {
8255 6588123 TABLE *const table = use->table_ref->table;
8256
5/6
✓ Branch 0 taken 6588184 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 704636 times.
✓ Branch 3 taken 5883548 times.
✓ Branch 4 taken 704394 times.
✓ Branch 5 taken 5883790 times.
7292759 if (use->val->const_for_execution() &&
8257
2/2
✓ Branch 0 taken 704395 times.
✓ Branch 1 taken 241 times.
704636 use->optimize != KEY_OPTIMIZE_REF_OR_NULL)
8258 704394 table->const_key_parts[use->key] |= use->keypart_map;
8259
2/2
✓ Branch 0 taken 6585966 times.
✓ Branch 1 taken 2218 times.
6588184 if (use->keypart != FT_KEYPART) {
8260
4/4
✓ Branch 0 taken 2214068 times.
✓ Branch 1 taken 4371898 times.
✓ Branch 2 taken 1070458 times.
✓ Branch 3 taken 1143610 times.
6585966 if (use->key == prev->key && use->table_ref == prev->table_ref) {
8261
2/2
✓ Branch 0 taken 1069806 times.
✓ Branch 1 taken 652 times.
1070458 if (prev->keypart + 1 < use->keypart ||
8262
4/4
✓ Branch 0 taken 413423 times.
✓ Branch 1 taken 656383 times.
✓ Branch 2 taken 124 times.
✓ Branch 3 taken 413299 times.
1069806 (prev->keypart == use->keypart && found_eq_constant))
8263 776 continue; /* remove */
8264
2/2
✓ Branch 0 taken 1846965 times.
✓ Branch 1 taken 3668543 times.
5515508 } else if (use->keypart != 0) // First found must be 0
8265 1846965 continue;
8266 }
8267
8268 /*
8269 Protect against self assignment.
8270 The compiler *may* generate a call to memcpy() to do the assignment,
8271 and that is undefined behaviour (memory overlap).
8272 */
8273
2/2
✓ Branch 0 taken 2581864 times.
✓ Branch 1 taken 2158579 times.
4740443 if (save_pos != use) *save_pos = *use;
8274 4740443 prev = use;
8275
1/2
✓ Branch 0 taken 4740478 times.
✗ Branch 1 not taken.
4740443 found_eq_constant = use->val->const_for_execution();
8276 /* Save ptr to first use */
8277
2/2
✓ Branch 0 taken 2513086 times.
✓ Branch 1 taken 2227398 times.
4740478 if (!table->reginfo.join_tab->keyuse())
8278 2513086 table->reginfo.join_tab->set_keyuse(save_pos);
8279 4740479 table->reginfo.join_tab->checked_keys.set_bit(use->key);
8280 4740428 save_pos++;
8281 }
8282 591882 i = (uint)(save_pos - keyuse->begin());
8283 591905 keyuse->at(i) = key_end;
8284 591891 keyuse->chop(i);
8285 }
8286
1/2
✓ Branch 0 taken 1240828 times.
✗ Branch 1 not taken.
1240832 print_keyuse_array(thd, &thd->opt_trace, keyuse);
8287 /*
8288 Number of functions here call val_x() methods, which might throw an error.
8289 Catch those errors here.
8290 */
8291
1/2
✓ Branch 0 taken 1240843 times.
✗ Branch 1 not taken.
1240828 return thd->is_error();
8292 }
8293
8294 /**
8295 Create a keyuse array for a table with a primary key.
8296 To be used when creating a materialized temporary table.
8297
8298 @param thd THD pointer, for memory allocation
8299 @param keyparts Number of key parts in the primary key
8300 @param fields fields
8301 @param outer_exprs List of items used for key lookup
8302
8303 @return Pointer to created keyuse array, or NULL if error
8304 */
8305 4591 Key_use_array *create_keyuse_for_table(
8306 THD *thd, uint keyparts, Item_field **fields,
8307 const mem_root_deque<Item *> &outer_exprs) {
8308
1/2
✓ Branch 0 taken 4591 times.
✗ Branch 1 not taken.
4591 void *mem = thd->alloc(sizeof(Key_use_array));
8309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4591 times.
4591 if (!mem) return nullptr;
8310
1/2
✓ Branch 0 taken 4591 times.
✗ Branch 1 not taken.
4591 Key_use_array *keyuses = new (mem) Key_use_array(thd->mem_root);
8311
8312
1/2
✓ Branch 0 taken 4591 times.
✗ Branch 1 not taken.
4591 auto outer_expr_it = outer_exprs.begin();
8313
8314
2/2
✓ Branch 0 taken 4973 times.
✓ Branch 1 taken 4591 times.
9564 for (uint keypartno = 0; keypartno < keyparts; keypartno++) {
8315
2/4
✓ Branch 0 taken 4973 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4973 times.
✗ Branch 3 not taken.
4973 Item *const item = *outer_expr_it++;
8316 4973 Key_field key_field(fields[keypartno], item, 0, 0, true,
8317 // null_rejecting must be true for field items only,
8318 // add_not_null_conds() is incapable of handling
8319 // other item types.
8320
1/2
✓ Branch 0 taken 4973 times.
✗ Branch 1 not taken.
4973 (item->type() == Item::FIELD_ITEM), nullptr, UINT_MAX);
8321
2/4
✓ Branch 0 taken 4973 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4973 times.
4973 if (add_key_part(keyuses, &key_field)) return nullptr;
8322 }
8323 4591 const Key_use key_end(nullptr, nullptr, 0, 0, 0, 0, 0, 0, false, nullptr, 0);
8324
2/4
✓ Branch 0 taken 4591 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4591 times.
4591 if (keyuses->push_back(key_end)) // added for easy testing
8325 return nullptr;
8326
8327 4591 return keyuses;
8328 }
8329
8330 /**
8331 Move const tables first in the position array.
8332
8333 Increment the number of const tables and set same basic properties for the
8334 const table.
8335 A const table looked up by a key has type JT_CONST.
8336 A const table with a single row has type JT_SYSTEM.
8337
8338 @param tab Table that is designated as a const table
8339 @param key The key definition to use for this table (NULL if table scan)
8340 */
8341
8342 140457 void JOIN::mark_const_table(JOIN_TAB *tab, Key_use *key) {
8343 140457 POSITION *const position = positions + const_tables;
8344 140457 position->table = tab;
8345 140457 position->key = key;
8346 140457 position->rows_fetched = 1.0; // This is a const table
8347 140457 position->filter_effect = 1.0;
8348 140457 position->prefix_rowcount = 1.0;
8349 140457 position->read_cost = 0.0;
8350 140457 position->ref_depend_map = 0;
8351 140457 position->loosescan_key = MAX_KEY; // Not a LooseScan
8352 140457 position->sj_strategy = SJ_OPT_NONE;
8353 140457 positions->use_join_buffer = false;
8354
8355 // Move the const table as far down as possible in best_ref
8356 140457 JOIN_TAB **pos = best_ref + const_tables + 1;
8357
2/2
✓ Branch 0 taken 37266 times.
✓ Branch 1 taken 140457 times.
177723 for (JOIN_TAB *next = best_ref[const_tables]; next != tab; pos++) {
8358 37266 JOIN_TAB *const tmp = pos[0];
8359 37266 pos[0] = next;
8360 37266 next = tmp;
8361 }
8362 140457 best_ref[const_tables] = tab;
8363
8364
2/2
✓ Branch 0 taken 81375 times.
✓ Branch 1 taken 59082 times.
140457 tab->set_type(key ? JT_CONST : JT_SYSTEM);
8365
8366 140457 const_table_map |= tab->table_ref->map();
8367
8368 140457 const_tables++;
8369 140457 }
8370
8371 195165 void JOIN::make_outerjoin_info() {
8372
1/2
✓ Branch 0 taken 195257 times.
✗ Branch 1 not taken.
195165 DBUG_TRACE;
8373
8374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 195257 times.
195257 assert(query_block->outer_join);
8375
4/6
✓ Branch 0 taken 195234 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 195237 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 195241 times.
✗ Branch 5 not taken.
195257 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
8376
8377
1/2
✓ Branch 0 taken 195268 times.
✗ Branch 1 not taken.
195264 query_block->reset_nj_counters();
8378
8379
2/2
✓ Branch 0 taken 1517055 times.
✓ Branch 1 taken 195358 times.
1712413 for (uint i = const_tables; i < tables; ++i) {
8380 1517055 JOIN_TAB *const tab = best_ref[i];
8381 1517055 TABLE *const table = tab->table();
8382
2/2
✓ Branch 0 taken 306795 times.
✓ Branch 1 taken 1210379 times.
1517174 if (!table) continue;
8383
8384 1210379 TABLE_LIST *const tbl = tab->table_ref;
8385 /*
8386 If 'tbl' is inside a SJ/AJ nest served by materialization, we must
8387 limit setting first_inner, last_inner and first_upper for join nests
8388 inside the materialized table. Indeed it is the SJ-tmp table, and not
8389 'tbl', which interacts with the nests outer to the SJ/AJ nest.
8390 */
8391 const bool sj_mat_inner =
8392
1/2
✓ Branch 0 taken 1210427 times.
✗ Branch 1 not taken.
1210379 sj_is_materialize_strategy(tab->get_sj_strategy());
8393
8394
2/2
✓ Branch 0 taken 526679 times.
✓ Branch 1 taken 683751 times.
1210430 if (tbl->outer_join) {
8395 /*
8396 Table tab is the only one inner table for outer join.
8397 (Like table t4 for the table reference t3 LEFT JOIN t4 ON t3.a=t4.a
8398 is in the query above.)
8399 */
8400 526679 tab->set_last_inner(i);
8401 526661 tab->set_first_inner(i);
8402
1/2
✓ Branch 0 taken 526669 times.
✗ Branch 1 not taken.
526667 tab->init_join_cond_ref(tbl);
8403 526669 tab->cond_equal = tbl->cond_equal;
8404 /*
8405 If this outer join nest is embedded in another join nest,
8406 link the join-tabs:
8407 */
8408 526669 TABLE_LIST *const outer_join_nest = tbl->outer_join_nest();
8409
2/2
✓ Branch 0 taken 679 times.
✓ Branch 1 taken 525996 times.
526675 if (outer_join_nest) {
8410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 679 times.
679 assert(outer_join_nest->nested_join->first_nested != NO_PLAN_IDX);
8411
4/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 644 times.
✓ Branch 2 taken 646 times.
✓ Branch 3 taken 33 times.
714 if (!sj_mat_inner ||
8412
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 33 times.
35 (tab->emb_sj_nest->sj_inner_tables &
8413 35 best_ref[outer_join_nest->nested_join->first_nested]
8414 35 ->table_ref->map()))
8415 646 tab->set_first_upper(outer_join_nest->nested_join->first_nested);
8416 }
8417 }
8418
2/2
✓ Branch 0 taken 21388 times.
✓ Branch 1 taken 1203180 times.
1224568 for (TABLE_LIST *embedding = tbl->embedding; embedding;
8419 14218 embedding = embedding->embedding) {
8420 // When reaching the outer tables of the materialized temporary table,
8421 // the decoration for this table is complete.
8422
4/4
✓ Branch 0 taken 3293 times.
✓ Branch 1 taken 18095 times.
✓ Branch 2 taken 3192 times.
✓ Branch 3 taken 101 times.
21388 if (sj_mat_inner && embedding == tab->emb_sj_nest) break;
8423 // Ignore join nests that are not outer join nests:
8424
2/2
✓ Branch 0 taken 10743 times.
✓ Branch 1 taken 7453 times.
18196 if (!embedding->join_cond_optim()) continue;
8425 7453 NESTED_JOIN *const nested_join = embedding->nested_join;
8426
2/2
✓ Branch 0 taken 3475 times.
✓ Branch 1 taken 3978 times.
7453 if (!nested_join->nj_counter) {
8427 /*
8428 Table tab is the first inner table for nested_join.
8429 Save reference to it in the nested join structure.
8430 */
8431 3475 nested_join->first_nested = i;
8432 // The table's condition is set to point to the join nest's condition
8433
1/2
✓ Branch 0 taken 3475 times.
✗ Branch 1 not taken.
3475 tab->init_join_cond_ref(embedding);
8434 3475 tab->cond_equal = tbl->cond_equal;
8435
8436 3475 TABLE_LIST *const outer_join_nest = embedding->outer_join_nest();
8437
2/2
✓ Branch 0 taken 198 times.
✓ Branch 1 taken 3277 times.
3475 if (outer_join_nest) {
8438
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 198 times.
198 assert(outer_join_nest->nested_join->first_nested != NO_PLAN_IDX);
8439
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 192 times.
✓ Branch 2 taken 192 times.
✓ Branch 3 taken 6 times.
204 if (!sj_mat_inner ||
8440
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 (tab->emb_sj_nest->sj_inner_tables &
8441 6 best_ref[outer_join_nest->nested_join->first_nested]
8442 6 ->table_ref->map()))
8443 192 tab->set_first_upper(outer_join_nest->nested_join->first_nested);
8444 }
8445 }
8446
2/2
✓ Branch 0 taken 6615 times.
✓ Branch 1 taken 838 times.
7453 if (tab->first_inner() == NO_PLAN_IDX)
8447 6615 tab->set_first_inner(nested_join->first_nested);
8448 /*
8449 If including the sj-mat tmp table, this also implicitly
8450 includes the inner tables of the sj-nest.
8451 */
8452 7453 nested_join->nj_counter +=
8453
2/2
✓ Branch 0 taken 335 times.
✓ Branch 1 taken 7118 times.
7453 tab->sj_mat_exec() ? tab->sj_mat_exec()->table_count : 1;
8454
2/2
✓ Branch 0 taken 3978 times.
✓ Branch 1 taken 3475 times.
7453 if (nested_join->nj_counter < nested_join->nj_total) break;
8455 // Table tab is the last inner table for nested join.
8456 3475 best_ref[nested_join->first_nested]->set_last_inner(i);
8457 }
8458 }
8459 195358 }
8460
8461 /**
8462 Build a condition guarded by match variables for embedded outer joins.
8463 When generating a condition for a table as part of an outer join condition
8464 or the WHERE condition, the table in question may also be part of an
8465 embedded outer join. In such cases, the condition must be guarded by
8466 the match variable for this embedded outer join. Such embedded outer joins
8467 may also be recursively embedded in other joins.
8468
8469 The function recursively adds guards for a condition ascending from tab
8470 to root_tab, which is the first inner table of an outer join,
8471 or NULL if the condition being handled is the WHERE clause.
8472
8473 @param join the current join
8474 @param idx index of the first inner table for the inner-most outer join
8475 @param cond the predicate to be guarded (must be set)
8476 @param root_idx index of the inner table to stop at
8477 (is NO_PLAN_IDX if this is the WHERE clause)
8478
8479 @return
8480 - pointer to the guarded predicate, if success
8481 - NULL if error
8482 */
8483
8484 2690936 static Item *add_found_match_trig_cond(JOIN *join, plan_idx idx, Item *cond,
8485 plan_idx root_idx) {
8486
3/6
✓ Branch 0 taken 2690958 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2690961 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2690963 times.
✗ Branch 5 not taken.
2690936 ASSERT_BEST_REF_IN_JOIN_ORDER(join);
8487
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2690955 times.
2690941 assert(cond->is_bool_func());
8488
8489
2/2
✓ Branch 0 taken 4207 times.
✓ Branch 1 taken 2690896 times.
2695162 for (; idx != root_idx; idx = join->best_ref[idx]->first_upper()) {
8490
2/4
✓ Branch 0 taken 4207 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4207 times.
8414 if (!(cond = new Item_func_trig_cond(cond, nullptr, join, idx,
8491
1/2
✓ Branch 0 taken 4207 times.
✗ Branch 1 not taken.
8414 Item_func_trig_cond::FOUND_MATCH)))
8492 return nullptr;
8493
8494 4207 cond->quick_fix_field();
8495 4207 cond->update_used_tables();
8496 }
8497
8498 2690896 return cond;
8499 }
8500
8501 /**
8502 Helper for JOIN::attach_join_conditions().
8503 Attaches bits of 'join_cond' to each table in the range [first_inner,
8504 last_tab], with proper guards.
8505 If 'sj_mat_cond' is true, we do not see first_inner (and tables on the same
8506 level of it) as inner to anything, as they're at the top from the POV of
8507 the materialization of the tmp table. So, if the SJ-mat nest is A LJ B,
8508 A will get a part of condition without any guard; B will get another part
8509 with a guard on A->found_match. It's like pushing a WHERE.
8510 */
8511 530294 bool JOIN::attach_join_condition_to_nest(plan_idx first_inner,
8512 plan_idx last_tab, Item *join_cond,
8513 bool is_sj_mat_cond) {
8514 /*
8515 Add the constant part of the join condition to the first inner table
8516 of the outer join.
8517 */
8518 Item *cond =
8519 530294 make_cond_for_table(thd, join_cond, const_table_map, table_map(0), false);
8520
2/2
✓ Branch 0 taken 833 times.
✓ Branch 1 taken 529459 times.
530292 if (cond) {
8521
2/2
✓ Branch 0 taken 745 times.
✓ Branch 1 taken 88 times.
833 if (!is_sj_mat_cond) {
8522
1/2
✓ Branch 0 taken 745 times.
✗ Branch 1 not taken.
1490 cond = new Item_func_trig_cond(cond, nullptr, this, first_inner,
8523
1/2
✓ Branch 0 taken 745 times.
✗ Branch 1 not taken.
1490 Item_func_trig_cond::IS_NOT_NULL_COMPL);
8524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 745 times.
745 if (!cond) return true;
8525
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 745 times.
745 if (cond->fix_fields(thd, nullptr)) return true;
8526 }
8527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 745 times.
833 if (best_ref[first_inner]->and_with_condition(cond)) return true;
8528 }
8529 /*
8530 Split the non-constant part of the join condition into parts that
8531 can be attached to the inner tables of the outer join.
8532 */
8533
2/2
✓ Branch 0 taken 534397 times.
✓ Branch 1 taken 530267 times.
1064664 for (plan_idx i = first_inner; i <= last_tab; ++i) {
8534 534397 table_map prefix_tables = best_ref[i]->prefix_tables();
8535 534456 table_map added_tables = best_ref[i]->added_tables();
8536
8537 /*
8538 When handling the first inner table of an outer join, we may also
8539 reference all tables ahead of this table:
8540 */
8541
2/2
✓ Branch 0 taken 530274 times.
✓ Branch 1 taken 4199 times.
534473 if (i == first_inner) added_tables = prefix_tables;
8542 /*
8543 We need RAND_TABLE_BIT on the last inner table, in case there is a
8544 non-deterministic function in the join condition.
8545 (RAND_TABLE_BIT is set for the last table of the join plan,
8546 but this is not sufficient for join conditions, which may have a
8547 last inner table that is ahead of the last table of the join plan).
8548 */
8549
2/2
✓ Branch 0 taken 530269 times.
✓ Branch 1 taken 4204 times.
534473 if (i == last_tab) {
8550 530269 prefix_tables |= RAND_TABLE_BIT;
8551 530269 added_tables |= RAND_TABLE_BIT;
8552 }
8553 cond =
8554 534473 make_cond_for_table(thd, join_cond, prefix_tables, added_tables, false);
8555
2/2
✓ Branch 0 taken 2790 times.
✓ Branch 1 taken 531711 times.
534501 if (cond == nullptr) continue;
8556 /*
8557 If the table is part of an outer join that is embedded in the
8558 outer join currently being processed, wrap the condition in
8559 triggered conditions for match variables of such embedded outer joins.
8560 */
8561
3/4
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 531667 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 531708 times.
1063417 if (!(cond = add_found_match_trig_cond(
8562 531711 this, best_ref[i]->first_inner(), cond,
8563 is_sj_mat_cond ? NO_PLAN_IDX : first_inner)))
8564 return true;
8565
8566
2/2
✓ Branch 0 taken 531664 times.
✓ Branch 1 taken 44 times.
531708 if (!is_sj_mat_cond) {
8567 // Add the guard turning the predicate off for the null-complemented row.
8568
1/2
✓ Branch 0 taken 531587 times.
✗ Branch 1 not taken.
1063242 cond = new Item_func_trig_cond(cond, nullptr, this, first_inner,
8569
1/2
✓ Branch 0 taken 531655 times.
✗ Branch 1 not taken.
1063251 Item_func_trig_cond::IS_NOT_NULL_COMPL);
8570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 531655 times.
531655 if (!cond) return true;
8571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 531631 times.
531655 if (cond->fix_fields(thd, nullptr)) return true;
8572 }
8573 // Add the generated condition to the existing table condition
8574
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 531670 times.
531675 if (best_ref[i]->and_with_condition(cond)) return true;
8575 }
8576 530267 return false;
8577 }
8578
8579 /**
8580 Attach outer join conditions to generated table conditions in an optimal way.
8581
8582 @param last_tab - Last table that has been added to the current plan.
8583 Pre-condition: If this is the last inner table of an outer
8584 join operation, a join condition is attached to the first
8585 inner table of that outer join operation.
8586
8587 @return false if success, true if error.
8588
8589 Outer join conditions are attached to individual tables, but we can analyze
8590 those conditions only when reaching the last inner table of an outer join
8591 operation. Notice also that a table can be last within several outer join
8592 nests, hence the outer for() loop of this function.
8593
8594 Example:
8595 SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.a=t2.a
8596
8597 Table t3 is last both in the join nest (t2 - t3) and in (t1 - (t2 - t3))
8598 Thus, join conditions for both join nests will be evaluated when reaching
8599 this table.
8600
8601 For each outer join operation processed, the join condition is split
8602 optimally over the inner tables of the outer join. The split-out conditions
8603 are later referred to as table conditions (but note that several table
8604 conditions stemming from different join operations may be combined into
8605 a composite table condition).
8606
8607 Example:
8608 Consider the above query once more.
8609 The predicate t1.a=t2.a can be evaluated when rows from t1 and t2 are ready,
8610 ie at table t2. The predicate t2.a=t3.a can be evaluated at table t3.
8611
8612 Each non-constant split-out table condition is guarded by a match variable
8613 that enables it only when a matching row is found for all the embedded
8614 outer join operations.
8615
8616 Each split-out table condition is guarded by a variable that turns the
8617 condition off just before a null-complemented row for the outer join
8618 operation is formed. Thus, the join condition will not be checked for
8619 the null-complemented row.
8620 */
8621
8622 3779669 bool JOIN::attach_join_conditions(plan_idx last_tab) {
8623
1/2
✓ Branch 0 taken 3779813 times.
✗ Branch 1 not taken.
3779669 DBUG_TRACE;
8624
4/6
✓ Branch 0 taken 3779822 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3779804 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 3779811 times.
✗ Branch 5 not taken.
3779813 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
8625
8626 3779802 JOIN_TAB *lt = best_ref[last_tab];
8627
8628 3779802 for (plan_idx first_inner = lt->first_inner();
8629
6/6
✓ Branch 0 taken 533991 times.
✓ Branch 1 taken 3775834 times.
✓ Branch 2 taken 530071 times.
✓ Branch 3 taken 3924 times.
✓ Branch 4 taken 530068 times.
✓ Branch 5 taken 3779761 times.
4843820 first_inner != NO_PLAN_IDX &&
8630 533991 best_ref[first_inner]->last_inner() == last_tab;
8631 530048 first_inner = best_ref[first_inner]->first_upper()) {
8632 /*
8633 Table last_tab is the last inner table of an outer join, locate
8634 the corresponding join condition from the first inner table of the
8635 same outer join:
8636 */
8637 530068 Item *const join_cond = best_ref[first_inner]->join_cond();
8638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 530073 times.
530073 assert(join_cond);
8639
2/4
✓ Branch 0 taken 530048 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 530048 times.
530073 if (attach_join_condition_to_nest(first_inner, last_tab, join_cond, false))
8640 return true;
8641 }
8642
3/4
✓ Branch 0 taken 3779807 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8442 times.
✓ Branch 3 taken 3771375 times.
3779761 if (sj_is_materialize_strategy(lt->get_sj_strategy())) {
8643 8442 plan_idx mat_tbl = NO_PLAN_IDX;
8644 /*
8645 The SJ nest's condition contains both the SJ equality condition and the
8646 WHERE of the replaced subquery. This WHERE must be pushed to SJ-inner
8647 tables for evaluation during materialization!
8648 */
8649 8442 Semijoin_mat_exec *sjm = nullptr;
8650 8442 for (plan_idx j = last_tab;; j--) {
8651 41925 sjm = best_ref[j]->sj_mat_exec();
8652
4/4
✓ Branch 0 taken 8560 times.
✓ Branch 1 taken 33365 times.
✓ Branch 2 taken 8442 times.
✓ Branch 3 taken 118 times.
41925 if (sjm && sjm->sj_nest == lt->emb_sj_nest) {
8653 // 'j' is the sj-mat tmp table
8654 8442 mat_tbl = j;
8655 8442 break;
8656 }
8657 }
8658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8442 times.
8442 assert(sjm);
8659
2/2
✓ Branch 0 taken 4583 times.
✓ Branch 1 taken 3859 times.
8442 if (sjm->inner_table_index + sjm->table_count - 1 == (uint)last_tab) {
8660 // we're at last table of sjmat nest
8661 4583 auto join_cond = best_ref[mat_tbl]->join_cond();
8662
5/8
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 4363 times.
✓ Branch 2 taken 220 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 220 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4583 times.
4583 if (join_cond && attach_join_condition_to_nest(sjm->inner_table_index,
8663 last_tab, join_cond, true))
8664 return true;
8665 }
8666 }
8667
8668 /*
8669 See if 'last_tab' is the first inner of an antijoin nest,
8670 then add a IS NULL condition on it.
8671 By attaching the condition to the first inner table, we know that if
8672 it is not satisfied we can just jump back to the table right before
8673 it.
8674 */
8675
4/4
✓ Branch 0 taken 571 times.
✓ Branch 1 taken 43192 times.
✓ Branch 2 taken 491 times.
✓ Branch 3 taken 80 times.
44334 if (lt->table_ref->embedding && lt->table_ref->embedding->is_aj_nest() &&
8676
6/6
✓ Branch 0 taken 43763 times.
✓ Branch 1 taken 3736054 times.
✓ Branch 2 taken 346 times.
✓ Branch 3 taken 75 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 3779401 times.
3824081 last_tab == lt->first_inner() &&
8677 /*
8678 Exception: in A AJ (B LJ C) where C is a single table: there is no
8679 join nest for C as it's single; C->embedding is thus the AJ nest; but
8680 C->first_inner() is C (as it's the first inner of the LJ operation).
8681 In that case it's not the first inner table of the AJ.
8682 Catch this case:
8683 */
8684 491 !lt->table_ref->join_cond()) {
8685
1/2
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
692 Item *cond = new Item_func_false();
8686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 346 times.
346 if (!cond) return true;
8687 // This is a signal for JOIN::create_access_paths
8688 346 cond->item_name.set(antijoin_null_cond);
8689 /*
8690 For A AJ B ON COND, we need an IS NULL condition which
8691 is tested on the result rows of A LEFT JOIN B ON COND.
8692 It must be tested only after the "match status" of a row of B has been
8693 decided, so is wrapped in a condition triggered by B->found_match.
8694 To have it test IS NULL, it's wrapped in a triggered condition which is
8695 false if B is not NULL-complemented.
8696 We needn't wrap this condition with triggers from upper nests, hence the
8697 last argument of the call below.
8698 */
8699
1/2
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
346 cond = add_found_match_trig_cond(this, last_tab, cond, lt->first_upper());
8700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 346 times.
346 if (!cond) return true;
8701
1/2
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
692 cond = new Item_func_trig_cond(cond, nullptr, this, last_tab,
8702
1/2
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
692 Item_func_trig_cond::IS_NOT_NULL_COMPL);
8703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 346 times.
346 if (!cond) return true;
8704
2/4
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 346 times.
346 if (cond->fix_fields(thd, nullptr)) return true;
8705
2/4
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 346 times.
346 if (lt->and_with_condition(cond)) return true;
8706 346 lt->table()->reginfo.not_exists_optimize = true;
8707
8708 // The relevant secondary engines don't support antijoin, so don't enable
8709 // this optimization for them.
8710
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 322 times.
346 assert(thd->secondary_engine_optimization() !=
8711 Secondary_engine_optimization::SECONDARY);
8712 }
8713
8714 3779723 return false;
8715 3779723 }
8716
8717 /*****************************************************************************
8718 Remove calculation with tables that aren't yet read. Remove also tests
8719 against fields that are read through key where the table is not a
8720 outer join table.
8721 We can't remove tests that are made against columns which are stored
8722 in sorted order.
8723 *****************************************************************************/
8724
8725 3137681 static Item *part_of_refkey(TABLE *table, TABLE_REF *ref, const Field *field) {
8726 3137681 uint ref_parts = ref->key_parts;
8727
2/2
✓ Branch 0 taken 2466732 times.
✓ Branch 1 taken 670949 times.
3137681 if (ref_parts) {
8728
2/2
✓ Branch 0 taken 568 times.
✓ Branch 1 taken 2466146 times.
2466732 if (ref->has_guarded_conds()) return nullptr;
8729
8730 2466146 const KEY_PART_INFO *key_part = table->key_info[ref->key].key_part;
8731
8732
2/2
✓ Branch 0 taken 2910553 times.
✓ Branch 1 taken 102785 times.
3013338 for (uint part = 0; part < ref_parts; part++, key_part++)
8733
4/4
✓ Branch 0 taken 2363845 times.
✓ Branch 1 taken 546688 times.
✓ Branch 2 taken 2363341 times.
✓ Branch 3 taken 547192 times.
5274398 if (field->eq(key_part->field) &&
8734
2/2
✓ Branch 0 taken 2363337 times.
✓ Branch 1 taken 508 times.
2363845 !(key_part->key_part_flag & HA_PART_KEY_SEG))
8735 2363341 return ref->items[part];
8736 }
8737 773734 return nullptr;
8738 }
8739
8740 2352940 bool ref_lookup_subsumes_comparison(Field *field, Item *right_item) {
8741 2352940 right_item = right_item->real_item();
8742
2/2
✓ Branch 0 taken 1846022 times.
✓ Branch 1 taken 506987 times.
2353002 if (right_item->type() == Item::FIELD_ITEM)
8743 1846022 return (field->eq_def(down_cast<Item_field *>(right_item)->field));
8744 /* remove equalities injected by IN->EXISTS transformation */
8745
2/2
✓ Branch 0 taken 1231 times.
✓ Branch 1 taken 505740 times.
506987 else if (right_item->type() == Item::CACHE_ITEM)
8746 1231 return down_cast<Item_cache *>(right_item)->eq_def(field);
8747
6/6
✓ Branch 0 taken 505546 times.
✓ Branch 1 taken 199 times.
✓ Branch 2 taken 505527 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 505527 times.
✓ Branch 5 taken 215 times.
505740 if (right_item->const_for_execution() && !right_item->is_null()) {
8748 /*
8749 We can remove all fields except:
8750 1. String data types:
8751 - For BINARY/VARBINARY fields with equality against a
8752 string: Ref access can return more rows than match the
8753 string. The reason seems to be that the string constant
8754 is not "padded" to the full length of the field when
8755 setting up ref access. @todo Change how ref access for
8756 BINARY/VARBINARY fields are done so that only qualifying
8757 rows are returned from the storage engine.
8758 2. Float data type: Comparison of float can differ
8759 - When we search "WHERE field=value" using an index,
8760 the "value" side is converted from double to float by
8761 Field_float::store(), then two floats are compared.
8762 - When we search "WHERE field=value" without indexes,
8763 the "field" side is converted from float to double by
8764 Field_float::val_real(), then two doubles are compared.
8765 */
8766
4/4
✓ Branch 0 taken 25918 times.
✓ Branch 1 taken 479607 times.
✓ Branch 2 taken 693 times.
✓ Branch 3 taken 504831 times.
531444 if (field->type() == MYSQL_TYPE_STRING &&
8767
2/2
✓ Branch 0 taken 693 times.
✓ Branch 1 taken 25224 times.
25918 field->charset()->pad_attribute == NO_PAD) {
8768 /*
8769 For "NO PAD" collations on CHAR columns, this function must return
8770 false, because removal of trailing space in CHAR columns makes the
8771 table value and the index value compare differently. As the column
8772 strips trailing spaces, it can return false candidates. Further
8773 comparison of the actual table values is required.
8774 */
8775 693 return false;
8776 }
8777 504831 if (!((field->type() == MYSQL_TYPE_STRING || // 1
8778
2/2
✓ Branch 0 taken 457584 times.
✓ Branch 1 taken 22022 times.
479603 field->type() == MYSQL_TYPE_VARCHAR) &&
8779
6/6
✓ Branch 0 taken 479603 times.
✓ Branch 1 taken 25225 times.
✓ Branch 2 taken 482715 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 504815 times.
✓ Branch 5 taken 7 times.
1467214 field->binary()) &&
8780
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 504796 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
504737 !(field->type() == MYSQL_TYPE_FLOAT && field->decimals() > 0)) // 2
8781 {
8782 504815 return !right_item->save_in_field_no_warnings(field, true);
8783 }
8784 }
8785 222 return false;
8786 }
8787
8788 /**
8789 @brief
8790 Identify redundant predicates.
8791
8792 @details
8793 Test if the equality predicate 'left_item = right_item' is redundant
8794 due to a REF-access already being set up on the table, where 'left_item' is
8795 part of the REF-key being used, and 'right_item' is equal to the key value
8796 specified for that field in the key.
8797 In such cases the predicate is known to be 'true' for any rows retrieved
8798 from that table. Thus it is redundant.
8799
8800 @param left_item The Item_field possibly being part of A ref-KEY.
8801 @param right_item The equality value specified for 'left_item'.
8802
8803 @return 'true' if the predicate is redundant.
8804
8805 @note See comments in reduce_cond_for_table() about careful
8806 usage/modifications of test_if_ref().
8807 */
8808
8809 3141711 static bool test_if_ref(Item_field *left_item, Item *right_item) {
8810
2/2
✓ Branch 0 taken 2638 times.
✓ Branch 1 taken 3139073 times.
3141711 if (left_item->depended_from)
8811 2638 return false; // don't even read join_tab of inner subquery!
8812 3139073 Field *field = left_item->field;
8813 3139073 JOIN_TAB *join_tab = field->table->reginfo.join_tab;
8814
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 3138943 times.
3139073 if (join_tab == nullptr) return false;
8815
8816
4/6
✓ Branch 0 taken 3139067 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3139062 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 3139042 times.
✗ Branch 5 not taken.
3138943 ASSERT_BEST_REF_IN_JOIN_ORDER(join_tab->join());
8817
8818 // No need to change const test
8819
6/6
✓ Branch 0 taken 3138615 times.
✓ Branch 1 taken 421 times.
✓ Branch 2 taken 3137718 times.
✓ Branch 3 taken 903 times.
✓ Branch 4 taken 3137719 times.
✓ Branch 5 taken 1323 times.
6277657 if (!field->table->const_table &&
8820 /* "ref_or_null" implements "x=y or x is null", not "x=y" */
8821 3138615 (join_tab->type() != JT_REF_OR_NULL)) {
8822 3137719 Item *ref_item = part_of_refkey(field->table, &join_tab->ref(), field);
8823
4/4
✓ Branch 0 taken 2363350 times.
✓ Branch 1 taken 774374 times.
✓ Branch 2 taken 2352817 times.
✓ Branch 3 taken 10369 times.
5490719 return (ref_item && ref_item->eq(right_item, true) &&
8824
2/2
✓ Branch 0 taken 2345846 times.
✓ Branch 1 taken 7149 times.
5490555 ref_lookup_subsumes_comparison(field, right_item));
8825 }
8826 1323 return false; // keep predicate
8827 }
8828
8829 /**
8830 @brief
8831 Remove redundant predicates from condition, return the reduced condition.
8832
8833 @details
8834 A predicate of the form 'field = value' may be redundant if the
8835 (ref-) access chosen for the table use an index containing 'field',
8836 where 'value' is specified as (part of) its ref-key. This method remove
8837 such redundant predicates, thus reducing the condition, possibly
8838 eliminating it entirely.
8839
8840 If comparing 'values' against outer-joined tables, these are possibly
8841 'null-extended'. Thus the usage of these values in the ref-key, is not
8842 sufficient anymore to guarantee that 'field = value' is 'TRUE'.
8843 The 'null_extended' argument hold the table_map of any such possibly
8844 null-extended tables which are excluded from the above 'reduce' logic.
8845
8846 Any tables referred in Item_func_trig_cond(FOUND_MATCH) conditions are
8847 aggregated into this null_extended table_map.
8848
8849 @param cond The condition to be 'reduced'.
8850 @param null_extended table_map of possibly null-extended outer-tables.
8851
8852 @return The condition with redundant predicates removed,
8853 possibly nullptr.
8854 */
8855 6398066 static Item *reduce_cond_for_table(Item *cond, table_map null_extended) {
8856
1/2
✓ Branch 0 taken 6398253 times.
✗ Branch 1 not taken.
6398066 DBUG_TRACE;
8857
5/8
✓ Branch 0 taken 6398248 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 6398241 times.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
6398253 DBUG_EXECUTE("where",
8858 print_where(current_thd, cond, "cond term", QT_ORDINARY););
8859
8860
3/4
✓ Branch 0 taken 6398220 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1190761 times.
✓ Branch 3 taken 5207459 times.
6398248 if (cond->type() == Item::COND_ITEM) {
8861 1190761 List<Item> *arguments = down_cast<Item_cond *>(cond)->argument_list();
8862
1/2
✓ Branch 0 taken 1190766 times.
✗ Branch 1 not taken.
1190768 List_iterator<Item> li(*arguments);
8863
3/4
✓ Branch 0 taken 1190726 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1165000 times.
✓ Branch 3 taken 25726 times.
1190766 if (down_cast<Item_cond *>(cond)->functype() == Item_func::COND_AND_FUNC) {
8864 Item *item;
8865
2/2
✓ Branch 0 taken 3102769 times.
✓ Branch 1 taken 1165029 times.
4267787 while ((item = li++)) {
8866
1/2
✓ Branch 0 taken 3102806 times.
✗ Branch 1 not taken.
3102769 Item *upd_item = reduce_cond_for_table(item, null_extended);
8867
2/2
✓ Branch 0 taken 1224090 times.
✓ Branch 1 taken 1878716 times.
3102806 if (upd_item == nullptr) {
8868
1/2
✓ Branch 0 taken 1224071 times.
✗ Branch 1 not taken.
1224090 li.remove();
8869
2/2
✓ Branch 0 taken 1869 times.
✓ Branch 1 taken 1876847 times.
1878716 } else if (upd_item != item) {
8870 1869 li.replace(upd_item);
8871 }
8872 }
8873
3/3
✓ Branch 0 taken 308517 times.
✓ Branch 1 taken 131985 times.
✓ Branch 2 taken 724527 times.
1165029 switch (arguments->elements) {
8874 308517 case 0:
8875 440537 return nullptr; // All 'true' -> And-cond true
8876 131985 case 1:
8877 131985 return arguments->head();
8878 }
8879 } else { // Or list
8880 Item *item;
8881
2/2
✓ Branch 0 taken 67364 times.
✓ Branch 1 taken 25707 times.
93071 while ((item = li++)) {
8882
1/2
✓ Branch 0 taken 67378 times.
✗ Branch 1 not taken.
67364 Item *upd_item = reduce_cond_for_table(item, null_extended);
8883
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 67345 times.
67378 if (upd_item == nullptr) {
8884 33 return nullptr; // Term 'true' -> entire Or-cond true
8885
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 67293 times.
67345 } else if (upd_item != item) {
8886 52 li.replace(upd_item);
8887 }
8888 }
8889 }
8890
3/4
✓ Branch 0 taken 5207397 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5206888 times.
✓ Branch 3 taken 509 times.
5207459 } else if (cond->type() == Item::FUNC_ITEM) {
8891 5206888 Item_func *func = down_cast<Item_func *>(cond);
8892
3/4
✓ Branch 0 taken 5206812 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 540231 times.
✓ Branch 3 taken 4666581 times.
5206999 if (func->functype() == Item_func::TRIG_COND_FUNC) {
8893 540231 Item_func_trig_cond *func_trig = down_cast<Item_func_trig_cond *>(func);
8894
2/2
✓ Branch 0 taken 4207 times.
✓ Branch 1 taken 536002 times.
540222 if (func_trig->get_trig_type() == Item_func_trig_cond::FOUND_MATCH) {
8895 /*
8896 All inner-tables are possible null-extended when evaluating
8897 the 'FOUND_MATCH'. Thus, predicates embedded in this trig_cond,
8898 referring these tables, should not be eliminated.
8899 -> Add to null_extended map.
8900 */
8901
1/2
✓ Branch 0 taken 4207 times.
✗ Branch 1 not taken.
4207 null_extended |= func_trig->get_inner_tables();
8902 }
8903
8904
1/2
✓ Branch 0 taken 540294 times.
✗ Branch 1 not taken.
540209 Item *cond_arg = func->arguments()[0];
8905
1/2
✓ Branch 0 taken 540326 times.
✗ Branch 1 not taken.
540294 Item *upd_arg = reduce_cond_for_table(cond_arg, null_extended);
8906
2/2
✓ Branch 0 taken 514957 times.
✓ Branch 1 taken 25369 times.
540326 if (upd_arg == nullptr) {
8907 514957 return nullptr;
8908 }
8909
1/2
✓ Branch 0 taken 25371 times.
✗ Branch 1 not taken.
25369 func->arguments()[0] = upd_arg;
8910 }
8911
8912
3/4
✓ Branch 0 taken 4666596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2993717 times.
✓ Branch 3 taken 1672879 times.
4666581 else if (func->functype() == Item_func::EQ_FUNC) {
8913 /*
8914 Remove equalities that are guaranteed to be true by use of 'ref' access
8915 method.
8916 Note that ref access implements "table1.field1 <=>
8917 table2.indexed_field2", i.e. if it passed a NULL field1, it will return
8918 NULL indexed_field2 if there are.
8919 Thus the equality "table1.field1 = table2.indexed_field2",
8920 is equivalent to "ref access AND table1.field1 IS NOT NULL"
8921 i.e. "ref access and proper setting/testing of ref->null_rejecting".
8922 Thus, we must be careful, that when we remove equalities below we also
8923 set ref->null_rejecting, and test it at execution; otherwise wrong NULL
8924 matches appear.
8925 So:
8926 - for the optimization phase, the code which is below, and the code in
8927 test_if_ref(), and in add_key_field(), must be kept in sync: if the
8928 applicability conditions in one place are relaxed, they should also be
8929 relaxed elsewhere.
8930 - for the execution phase, all possible execution methods must test
8931 ref->null_rejecting.
8932 */
8933
2/4
✓ Branch 0 taken 2993769 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2993752 times.
✗ Branch 3 not taken.
2993717 Item *left_item = func->arguments()[0]->real_item();
8934
2/4
✓ Branch 0 taken 2993791 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2993788 times.
✗ Branch 3 not taken.
2993752 Item *right_item = func->arguments()[1]->real_item();
8935
1/2
✓ Branch 0 taken 2993779 times.
✗ Branch 1 not taken.
2993788 if ((left_item->type() == Item::FIELD_ITEM &&
8936
3/4
✓ Branch 0 taken 2967176 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2966676 times.
✓ Branch 3 taken 500 times.
2967176 !(left_item->used_tables() & null_extended) &&
8937
7/8
✓ Branch 0 taken 2967176 times.
✓ Branch 1 taken 26603 times.
✓ Branch 2 taken 2966691 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 622521 times.
✓ Branch 5 taken 2344170 times.
✓ Branch 6 taken 2345827 times.
✓ Branch 7 taken 647963 times.
6610075 test_if_ref(down_cast<Item_field *>(left_item), right_item)) ||
8938
3/4
✓ Branch 0 taken 649620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 176336 times.
✓ Branch 3 taken 473284 times.
649624 (right_item->type() == Item::FIELD_ITEM &&
8939
3/4
✓ Branch 0 taken 176336 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 175141 times.
✓ Branch 3 taken 1195 times.
176336 !(right_item->used_tables() & null_extended) &&
8940
3/4
✓ Branch 0 taken 175141 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1660 times.
✓ Branch 3 taken 173481 times.
175141 test_if_ref(down_cast<Item_field *>(right_item), left_item))) {
8941 2345827 return nullptr;
8942 }
8943 }
8944 }
8945 3096956 return cond;
8946 6398277 }
8947
8948 /**
8949 @brief
8950 Remove redundant predicates and cache constant expressions.
8951
8952 @details
8953 Do a final round on pushed down table conditions and HAVING
8954 clause. Optimize them for faster execution by removing
8955 predicates being obsolete due to the access path selected
8956 for the table. Constant expressions are also cached
8957 to avoid evaluating them for each row being compared.
8958
8959 @return False if success, True if error
8960
8961 @note This function is run after conditions have been pushed down to
8962 individual tables, so transformation is applied to JOIN_TAB::condition
8963 and not to the WHERE condition.
8964 */
8965 1732077 bool JOIN::finalize_table_conditions() {
8966 /*
8967 Unnecessary to reduce conditions for const tables as they are only
8968 evaluated once.
8969 */
8970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1732188 times.
1732077 assert(!plan_is_const());
8971
4/6
✓ Branch 0 taken 1732176 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1732176 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1732176 times.
✗ Branch 5 not taken.
1732188 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
8972
8973 1732188 Opt_trace_context *const trace = &thd->opt_trace;
8974
1/2
✓ Branch 0 taken 1732193 times.
✗ Branch 1 not taken.
1732188 Opt_trace_object trace_wrapper(trace);
8975
1/2
✓ Branch 0 taken 1732194 times.
✗ Branch 1 not taken.
1732193 Opt_trace_array trace_tables(trace, "finalizing_table_conditions");
8976
8977
2/2
✓ Branch 0 taken 6079491 times.
✓ Branch 1 taken 1732349 times.
7811840 for (uint i = const_tables; i < tables; i++) {
8978 6079491 Item *condition = best_ref[i]->condition();
8979
2/2
✓ Branch 0 taken 3391908 times.
✓ Branch 1 taken 2687668 times.
6079576 if (condition == nullptr) continue;
8980
8981 /*
8982 Table predicates known to be true by the selected
8983 (ref-)access method may be removed from the condition
8984 */
8985
1/2
✓ Branch 0 taken 2687762 times.
✗ Branch 1 not taken.
2687668 Opt_trace_object trace_cond(trace);
8986
1/2
✓ Branch 0 taken 2687763 times.
✗ Branch 1 not taken.
2687762 trace_cond.add_utf8_table(best_ref[i]->table_ref);
8987
1/2
✓ Branch 0 taken 2687759 times.
✗ Branch 1 not taken.
2687763 trace_cond.add("original_table_condition", condition);
8988
8989 /*
8990 Calculate the set of possibly NULL extended tables when 'condition'
8991 is evaluated. As it is evaluated on a found row from table, that
8992 table is subtracted from the nullable tables. Note that a FOUND_MATCH
8993 trigger is a special case, handled in reduce_cond_for_table().
8994 */
8995 const table_map null_extended =
8996 2687759 query_block->outer_join & ~best_ref[i]->table_ref->map();
8997
1/2
✓ Branch 0 taken 2687791 times.
✗ Branch 1 not taken.
2687775 condition = reduce_cond_for_table(condition, null_extended);
8998
3/4
✓ Branch 0 taken 1257525 times.
✓ Branch 1 taken 1430266 times.
✓ Branch 2 taken 1257524 times.
✗ Branch 3 not taken.
2687791 if (condition != nullptr) condition->update_used_tables();
8999
9000 /*
9001 Cache constant expressions in table conditions.
9002 (Moved down from WHERE- and ON-clauses)
9003 */
9004
2/2
✓ Branch 0 taken 1257524 times.
✓ Branch 1 taken 1430266 times.
2687790 if (condition != nullptr) {
9005
1/2
✓ Branch 0 taken 1257483 times.
✗ Branch 1 not taken.
1257524 cache_const_expr_arg cache_arg;
9006 1257483 cache_const_expr_arg *analyzer_arg = &cache_arg;
9007
1/2
✓ Branch 0 taken 1257527 times.
✗ Branch 1 not taken.
1257483 condition = condition->compile(
9008 &Item::cache_const_expr_analyzer, (uchar **)&analyzer_arg,
9009 &Item::cache_const_expr_transformer, (uchar *)&cache_arg);
9010
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1257526 times.
1257527 if (condition == nullptr) return true;
9011 }
9012
9013
1/2
✓ Branch 0 taken 2687738 times.
✗ Branch 1 not taken.
2687792 trace_cond.add("final_table_condition ", condition);
9014 2687738 best_ref[i]->set_condition(condition);
9015
1/2
✓ Branch 0 taken 2687738 times.
✗ Branch 1 not taken.
2687780 }
9016
9017 /* Cache constant expressions in HAVING-clauses. */
9018
2/2
✓ Branch 0 taken 8524 times.
✓ Branch 1 taken 1723825 times.
1732349 if (having_cond != nullptr) {
9019
1/2
✓ Branch 0 taken 8524 times.
✗ Branch 1 not taken.
8524 cache_const_expr_arg cache_arg;
9020 8524 cache_const_expr_arg *analyzer_arg = &cache_arg;
9021
1/2
✓ Branch 0 taken 8524 times.
✗ Branch 1 not taken.
8524 having_cond = having_cond->compile(
9022 &Item::cache_const_expr_analyzer, (uchar **)&analyzer_arg,
9023 &Item::cache_const_expr_transformer, (uchar *)&cache_arg);
9024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8524 times.
8524 if (having_cond == nullptr) return true;
9025 }
9026 1732349 return false;
9027 1732348 }
9028
9029 /**
9030 @brief
9031 Add keys to derived tables'/views' result tables in a list
9032
9033 @details
9034 This function generates keys for all derived tables/views of the query_block
9035 to which this join corresponds to with help of the TABLE_LIST:generate_keys
9036 function.
9037
9038 @return false all keys were successfully added.
9039 @return true OOM error
9040 */
9041
9042 2413 bool JOIN::generate_derived_keys() {
9043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2413 times.
2413 assert(query_block->materialized_derived_table_count);
9044
9045
2/2
✓ Branch 0 taken 5581 times.
✓ Branch 1 taken 2413 times.
7994 for (TABLE_LIST *table = query_block->leaf_tables; table;
9046 5581 table = table->next_leaf) {
9047 5581 table->derived_keys_ready = true;
9048 /* Process tables that aren't materialized yet. */
9049
5/6
✓ Branch 0 taken 2769 times.
✓ Branch 1 taken 2812 times.
✓ Branch 2 taken 2177 times.
✓ Branch 3 taken 592 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5581 times.
7758 if (table->uses_materialization() && !table->table->is_created() &&
9050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2177 times.
2177 table->generate_keys())
9051 return true;
9052 }
9053 2413 return false;
9054 }
9055
9056 /**
9057 For each materialized derived table/view, informs every TABLE of the key it
9058 will (not) use, segregates used keys from unused keys in TABLE::key_info,
9059 and eliminates unused keys.
9060 */
9061
9062 177564 void JOIN::finalize_derived_keys() {
9063
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177564 times.
177564 assert(query_block->materialized_derived_table_count);
9064
3/6
✓ Branch 0 taken 177564 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 177564 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 177564 times.
✗ Branch 5 not taken.
177564 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
9065
9066 177564 bool adjust_key_count = false;
9067 177564 table_map processed_tables = 0;
9068
9069
2/2
✓ Branch 0 taken 359737 times.
✓ Branch 1 taken 177564 times.
537301 for (uint i = 0; i < tables; i++) {
9070 359737 JOIN_TAB *tab = best_ref[i];
9071 359737 TABLE *table = tab->table();
9072 359737 TABLE_LIST *table_ref = tab->table_ref;
9073 /*
9074 Save chosen key description if:
9075 1) it's a materialized derived table
9076 2) it's not yet instantiated
9077 3) some keys are defined for it
9078 */
9079
2/2
✓ Branch 0 taken 178114 times.
✓ Branch 1 taken 3207 times.
181321 if (table && table_ref->uses_materialization() && // (1)
9080
6/6
✓ Branch 0 taken 181321 times.
✓ Branch 1 taken 178416 times.
✓ Branch 2 taken 175723 times.
✓ Branch 3 taken 2391 times.
✓ Branch 4 taken 2024 times.
✓ Branch 5 taken 357713 times.
716781 !table->is_created() && // (2)
9081
2/2
✓ Branch 0 taken 2024 times.
✓ Branch 1 taken 173699 times.
175723 table->s->keys > 0) // (3)
9082 {
9083 /*
9084 If there are two local references to the same CTE, and they use
9085 the same key, the iteration for the second reference is unnecessary.
9086 */
9087
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2013 times.
3063 if (processed_tables & table_ref->map()) continue;
9088
9089 2013 adjust_key_count = true;
9090
9091
1/2
✓ Branch 0 taken 2013 times.
✗ Branch 1 not taken.
2013 Key_map used_keys;
9092
9093 // Mark all unique indexes as in use, since they have an effect
9094 // (deduplication) whether any expression refers to them or not.
9095 // In particular, they are used if we want to materialize a UNION DISTINCT
9096 // directly into the derived table.
9097
2/2
✓ Branch 0 taken 11871 times.
✓ Branch 1 taken 2013 times.
13884 for (uint key_idx = 0; key_idx < table->s->keys; ++key_idx) {
9098
2/2
✓ Branch 0 taken 411 times.
✓ Branch 1 taken 11460 times.
11871 if (table->key_info[key_idx].flags & HA_NOSAME) {
9099 411 used_keys.set_bit(key_idx);
9100 }
9101 }
9102
9103 // Same for the hash key used for manual deduplication, if any. (It always
9104 // has index 0 if it exists.)
9105
2/2
✓ Branch 0 taken 187 times.
✓ Branch 1 taken 1826 times.
2013 if (table->hash_field) {
9106 187 used_keys.set_bit(0);
9107 }
9108
9109 2013 Key_use *const keyuse = tab->position()->key;
9110
6/6
✓ Branch 0 taken 1039 times.
✓ Branch 1 taken 974 times.
✓ Branch 2 taken 509 times.
✓ Branch 3 taken 530 times.
✓ Branch 4 taken 509 times.
✓ Branch 5 taken 1504 times.
2013 if (keyuse == nullptr && used_keys.is_clear_all()) {
9111 // Nothing uses any keys.
9112 509 tab->keys().clear_all();
9113 509 tab->const_keys.clear_all();
9114 509 continue;
9115 }
9116
9117 1504 Derived_refs_iterator it(table_ref);
9118
3/4
✓ Branch 0 taken 16051 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14547 times.
✓ Branch 3 taken 1504 times.
16051 while (TABLE *t = it.get_next()) {
9119 /*
9120 Eliminate possible keys created by this JOIN and which it
9121 doesn't use.
9122 Collect all keys of this table which are used by any reference in
9123 this query block. Any other query block doesn't matter as:
9124 - either it was optimized before, so it's not using a key we may
9125 want to drop.
9126 - or it was optimized in this same window, so:
9127 * either we own the window, then any key we may want to
9128 drop is not visible to it.
9129 * or it owns the window, then we are using only existing
9130 keys.
9131 - or it will be optimized after, so it's not using any key yet.
9132
9133 used_keys is a mix of possible used keys and existing used keys.
9134 */
9135
2/2
✓ Branch 0 taken 1551 times.
✓ Branch 1 taken 12996 times.
14547 if (t->pos_in_table_list->query_block == query_block) {
9136 1551 JOIN_TAB *jtab = t->reginfo.join_tab;
9137 1551 Key_use *keyuse_1 = jtab->position()->key;
9138
2/2
✓ Branch 0 taken 995 times.
✓ Branch 1 taken 556 times.
1551 if (keyuse_1) used_keys.set_bit(keyuse_1->key);
9139 }
9140 14547 }
9141
9142
1/2
✓ Branch 0 taken 1504 times.
✗ Branch 1 not taken.
1504 uint new_idx = table->s->find_first_unused_tmp_key(
9143 used_keys); // Also updates table->s->first_unused_tmp_key.
9144
2/2
✓ Branch 0 taken 530 times.
✓ Branch 1 taken 974 times.
1504 if (keyuse == nullptr) {
9145 530 continue;
9146 }
9147
9148 974 const uint old_idx = keyuse->key;
9149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 974 times.
974 assert(old_idx != new_idx);
9150
9151
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 962 times.
974 if (old_idx > new_idx) {
9152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 assert(table->s->owner_of_possible_tmp_keys == query_block);
9153 12 it.rewind();
9154
3/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 12 times.
25 while (TABLE *t = it.get_next()) {
9155 /*
9156 Unlike the collection of used_keys, references from other query
9157 blocks must be considered here, as they need a key_info array
9158 consistent with the to-be-changed table->s->keys.
9159 */
9160
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 t->move_tmp_key(old_idx, it.is_first());
9161 13 }
9162 } else
9163 962 new_idx = old_idx; // Index stays at same slot
9164
9165 /*
9166 If the key was created by earlier-optimized query blocks, and is
9167 already used by nonlocal references, those don't need any further
9168 update: they are already setup to use it and we're not moving the
9169 key.
9170 If the key was created by this query block, nonlocal references cannot
9171 possibly be referencing it.
9172 In both cases, only local references need to update their Key_use.
9173 */
9174 974 it.rewind();
9175
3/4
✓ Branch 0 taken 14778 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13804 times.
✓ Branch 3 taken 974 times.
14778 while (TABLE *t = it.get_next()) {
9176
2/2
✓ Branch 0 taken 12807 times.
✓ Branch 1 taken 997 times.
13804 if (t->pos_in_table_list->query_block != query_block) continue;
9177 997 JOIN_TAB *jtab = t->reginfo.join_tab;
9178 997 Key_use *keyuse_1 = jtab->position()->key;
9179
3/4
✓ Branch 0 taken 985 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 985 times.
✗ Branch 3 not taken.
997 if (keyuse_1 && keyuse_1->key == old_idx) {
9180 985 processed_tables |= t->pos_in_table_list->map();
9181 985 const bool key_is_const = jtab->const_keys.is_set(old_idx);
9182 // tab->keys() was never set, so must be set
9183 985 jtab->keys().clear_all();
9184 985 jtab->keys().set_bit(new_idx);
9185 985 jtab->const_keys.clear_all();
9186
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 956 times.
985 if (key_is_const) tab->const_keys.set_bit(new_idx);
9187 985 for (Key_use *kit = keyuse_1;
9188
4/4
✓ Branch 0 taken 1759 times.
✓ Branch 1 taken 506 times.
✓ Branch 2 taken 1280 times.
✓ Branch 3 taken 479 times.
2265 kit->table_ref == jtab->table_ref && kit->key == old_idx; kit++)
9189 1280 kit->key = new_idx;
9190 }
9191 13804 }
9192 }
9193 }
9194
9195
2/2
✓ Branch 0 taken 175725 times.
✓ Branch 1 taken 1839 times.
177564 if (!adjust_key_count) return;
9196
9197 // Finally we know how many keys remain in the table.
9198
2/2
✓ Branch 0 taken 6101 times.
✓ Branch 1 taken 1839 times.
7940 for (uint i = 0; i < tables; i++) {
9199 6101 JOIN_TAB *tab = best_ref[i];
9200 6101 TABLE *table = tab->table();
9201 6101 TABLE_LIST *table_ref = tab->table_ref;
9202
8/8
✓ Branch 0 taken 3965 times.
✓ Branch 1 taken 2136 times.
✓ Branch 2 taken 2099 times.
✓ Branch 3 taken 1866 times.
✓ Branch 4 taken 2047 times.
✓ Branch 5 taken 52 times.
✓ Branch 6 taken 2023 times.
✓ Branch 7 taken 4078 times.
8148 if (table && table_ref->uses_materialization() && !table->is_created() &&
9203
2/2
✓ Branch 0 taken 2023 times.
✓ Branch 1 taken 24 times.
2047 table->s->keys > 0) {
9204
2/2
✓ Branch 0 taken 457 times.
✓ Branch 1 taken 1566 times.
2023 if (table->s->owner_of_possible_tmp_keys != query_block) continue;
9205 /*
9206 Release lock. As a bonus, avoid double work when this loop
9207 later processes another local reference to the same table (similar to
9208 the processed_tables map in the first loop).
9209 */
9210 1566 table->s->owner_of_possible_tmp_keys = nullptr;
9211 1566 Derived_refs_iterator it(table_ref);
9212
4/6
✓ Branch 0 taken 23521 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21955 times.
✓ Branch 3 taken 1566 times.
✓ Branch 4 taken 21955 times.
✗ Branch 5 not taken.
23521 while (TABLE *t = it.get_next()) t->drop_unused_tmp_keys(it.is_first());
9213 }
9214 }
9215 }
9216
9217 /**
9218 @brief
9219 Extract a condition that can be checked after reading given table
9220
9221 @param thd Current session.
9222 @param cond Condition to analyze
9223 @param tables Tables for which "current field values" are available
9224 @param used_table Table(s) that we are extracting the condition for (may
9225 also include PSEUDO_TABLE_BITS, and may be zero)
9226 @param exclude_expensive_cond Do not push expensive conditions
9227
9228 @retval <>NULL Generated condition
9229 @retval = NULL Already checked, OR error
9230
9231 @details
9232 Extract the condition that can be checked after reading the table(s)
9233 specified in @c used_table, given that current-field values for tables
9234 specified in @c tables bitmap are available.
9235 If @c used_table is 0, extract conditions for all tables in @c tables.
9236
9237 This function can be used to extract conditions relevant for a table
9238 in a join order. Together with its caller, it will ensure that all
9239 conditions are attached to the first table in the join order where all
9240 necessary fields are available, and it will also ensure that a given
9241 condition is attached to only one table.
9242 To accomplish this, first initialize @c tables to the empty
9243 set. Then, loop over all tables in the join order, set @c used_table to
9244 the bit representing the current table, accumulate @c used_table into the
9245 @c tables set, and call this function. To ensure correct handling of
9246 const expressions and outer references, add the const table map and
9247 OUTER_REF_TABLE_BIT to @c used_table for the first table. To ensure
9248 that random expressions are evaluated for the final table, add
9249 RAND_TABLE_BIT to @c used_table for the final table.
9250
9251 The function assumes that constant, inexpensive parts of the condition
9252 have already been checked. Constant, expensive parts will be attached
9253 to the first table in the join order, provided that the above call
9254 sequence is followed.
9255
9256 The call order will ensure that conditions covering tables in @c tables
9257 minus those in @c used_table, have already been checked.
9258
9259 The function takes into account that some parts of the condition are
9260 guaranteed to be true by employed 'ref' access methods (the code that
9261 does this is located at the end, search down for "EQ_FUNC").
9262
9263 @note
9264 make_cond_for_info_schema() uses an algorithm similar to
9265 make_cond_for_table().
9266 */
9267
9268 25287429 Item *make_cond_for_table(THD *thd, Item *cond, table_map tables,
9269 table_map used_table, bool exclude_expensive_cond) {
9270 /*
9271 May encounter an Item_cache_int as "condition" here, so cannot
9272 assert that it satisfies is_bool_func().
9273 */
9274 /*
9275 Ignore this condition if
9276 1. We are extracting conditions for a specific table, and
9277 2. that table is not referenced by the condition, but not if
9278 3. this is a constant condition not checked at optimization time and
9279 this is the first table we are extracting conditions for.
9280 (Assuming that used_table == tables for the first table.)
9281 */
9282 45097712 if (used_table && // 1
9283
6/6
✓ Branch 0 taken 19810130 times.
✓ Branch 1 taken 5477299 times.
✓ Branch 2 taken 11013945 times.
✓ Branch 3 taken 8796194 times.
✓ Branch 4 taken 11014045 times.
✓ Branch 5 taken 14273528 times.
36301509 !(cond->used_tables() & used_table) && // 2
9284
4/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 11013972 times.
✓ Branch 2 taken 68 times.
✓ Branch 3 taken 40 times.
11013945 !(cond->is_expensive() && used_table == tables)) // 3
9285 11014045 return nullptr;
9286
9287
2/2
✓ Branch 0 taken 3132645 times.
✓ Branch 1 taken 11140974 times.
14273528 if (cond->type() == Item::COND_ITEM) {
9288
2/2
✓ Branch 0 taken 3086308 times.
✓ Branch 1 taken 46380 times.
3132645 if (((Item_cond *)cond)->functype() == Item_func::COND_AND_FUNC) {
9289 /* Create new top level AND item */
9290
2/4
✓ Branch 0 taken 3086210 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3086312 times.
✗ Branch 3 not taken.
3086308 Item_cond_and *new_cond = new Item_cond_and;
9291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3086312 times.
3086312 if (!new_cond) return nullptr;
9292
1/2
✓ Branch 0 taken 3086318 times.
✗ Branch 1 not taken.
3086312 List_iterator<Item> li(*((Item_cond *)cond)->argument_list());
9293 Item *item;
9294
2/2
✓ Branch 0 taken 19794527 times.
✓ Branch 1 taken 3086044 times.
22880752 while ((item = li++)) {
9295
1/2
✓ Branch 0 taken 19794503 times.
✗ Branch 1 not taken.
19794527 Item *fix = make_cond_for_table(thd, item, tables, used_table,
9296 exclude_expensive_cond);
9297
3/4
✓ Branch 0 taken 3662221 times.
✓ Branch 1 taken 16132282 times.
✓ Branch 2 taken 3662152 times.
✗ Branch 3 not taken.
19794503 if (fix) new_cond->argument_list()->push_back(fix);
9298 }
9299
3/3
✓ Branch 0 taken 1236672 times.
✓ Branch 1 taken 811368 times.
✓ Branch 2 taken 1038262 times.
3086044 switch (new_cond->argument_list()->elements) {
9300 1236672 case 0:
9301 1236672 return nullptr; // Always true
9302 811368 case 1:
9303 811368 return new_cond->argument_list()->head();
9304 1038262 default:
9305
2/4
✓ Branch 0 taken 1038192 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1038192 times.
1038262 if (new_cond->fix_fields(thd, nullptr)) return nullptr;
9306 1038192 return new_cond;
9307 }
9308 } else { // Or list
9309
2/4
✓ Branch 0 taken 46388 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46388 times.
✗ Branch 3 not taken.
46380 Item_cond_or *new_cond = new Item_cond_or;
9310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46388 times.
46388 if (!new_cond) return nullptr;
9311
1/2
✓ Branch 0 taken 46388 times.
✗ Branch 1 not taken.
46388 List_iterator<Item> li(*((Item_cond *)cond)->argument_list());
9312 Item *item;
9313
2/2
✓ Branch 0 taken 85854 times.
✓ Branch 1 taken 22885 times.
108739 while ((item = li++)) {
9314
1/2
✓ Branch 0 taken 85854 times.
✗ Branch 1 not taken.
85854 Item *fix = make_cond_for_table(thd, item, tables, table_map(0),
9315 exclude_expensive_cond);
9316
2/2
✓ Branch 0 taken 23503 times.
✓ Branch 1 taken 62351 times.
85854 if (!fix) return nullptr; // Always true
9317
1/2
✓ Branch 0 taken 62351 times.
✗ Branch 1 not taken.
62351 new_cond->argument_list()->push_back(fix);
9318 }
9319
2/4
✓ Branch 0 taken 22885 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 22885 times.
22885 if (new_cond->fix_fields(thd, nullptr)) return nullptr;
9320 22885 return new_cond;
9321 }
9322 }
9323
9324 /*
9325 Omit this condition if
9326 1. Some tables referred by the condition are not available, or
9327 2. We are extracting conditions for all tables, the condition is
9328 considered 'expensive', and we want to delay evaluation of such
9329 conditions to the execution phase.
9330 */
9331
6/6
✓ Branch 0 taken 4622281 times.
✓ Branch 1 taken 6518671 times.
✓ Branch 2 taken 152322 times.
✓ Branch 3 taken 4469959 times.
✓ Branch 4 taken 6518779 times.
✓ Branch 5 taken 4622173 times.
11293296 if ((cond->used_tables() & ~tables) || // 1
9332
4/4
✓ Branch 0 taken 86601 times.
✓ Branch 1 taken 65721 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 86512 times.
152322 (!used_table && exclude_expensive_cond && cond->is_expensive())) // 2
9333 6518779 return nullptr;
9334
9335 4622173 return cond;
9336 }
9337
9338 /**
9339 Separates the predicates in a join condition and pushes them to the
9340 join step where all involved tables are available in the join prefix.
9341 ON clauses from JOIN expressions are also pushed to the most appropriate step.
9342
9343 @param join Join object where predicates are pushed.
9344
9345 @param cond Pointer to condition which may contain an arbitrary number of
9346 predicates, combined using AND, OR and XOR items.
9347 If NULL, equivalent to a predicate that returns true for all
9348 row combinations.
9349
9350
9351 @retval true Found impossible WHERE clause, or out-of-memory
9352 @retval false Other
9353 */
9354
9355 1816566 static bool make_join_query_block(JOIN *join, Item *cond) {
9356
4/6
✓ Branch 0 taken 1191824 times.
✓ Branch 1 taken 624742 times.
✓ Branch 2 taken 1191860 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1191860 times.
1816566 assert(cond == nullptr || cond->is_bool_func());
9357 1816602 THD *thd = join->thd;
9358 1816602 Opt_trace_context *const trace = &thd->opt_trace;
9359
1/2
✓ Branch 0 taken 1816637 times.
✗ Branch 1 not taken.
1816602 DBUG_TRACE;
9360
4/6
✓ Branch 0 taken 1816638 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1816636 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1816636 times.
✗ Branch 5 not taken.
1816637 ASSERT_BEST_REF_IN_JOIN_ORDER(join);
9361
9362 // Add IS NOT NULL conditions to table conditions:
9363
2/4
✓ Branch 0 taken 1816640 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1816640 times.
1816635 if (add_not_null_conds(join)) return true;
9364
9365 /*
9366 Extract constant conditions that are part of the WHERE clause.
9367 Constant parts of join conditions from outer joins are attached to
9368 the appropriate table condition in JOIN::attach_join_conditions().
9369 */
9370
2/2
✓ Branch 0 taken 1191888 times.
✓ Branch 1 taken 624752 times.
1816640 if (cond) /* Because of GroupIndexSkipScanIterator */
9371 { /* there may be a select without a cond. */
9372
2/2
✓ Branch 0 taken 446922 times.
✓ Branch 1 taken 744966 times.
1191888 if (join->primary_tables > 1)
9373
1/2
✓ Branch 0 taken 446921 times.
✗ Branch 1 not taken.
446922 cond->update_used_tables(); // Table number may have changed
9374
4/4
✓ Branch 0 taken 78589 times.
✓ Branch 1 taken 1113302 times.
✓ Branch 2 taken 77294 times.
✓ Branch 3 taken 1114597 times.
1270476 if (join->plan_is_const() &&
9375 78589 join->query_block->master_query_expression() ==
9376
2/2
✓ Branch 0 taken 77294 times.
✓ Branch 1 taken 1295 times.
78589 thd->lex->unit) // The outer-most query block
9377 77294 join->const_table_map |= RAND_TABLE_BIT;
9378 }
9379 /*
9380 Extract conditions that depend on constant tables.
9381 The const part of the query's WHERE clause can be checked immediately
9382 and if it is not satisfied then the join has empty result
9383 */
9384 1816643 Item *const_cond = nullptr;
9385
2/2
✓ Branch 0 taken 1191891 times.
✓ Branch 1 taken 624752 times.
1816643 if (cond)
9386
1/2
✓ Branch 0 taken 1191870 times.
✗ Branch 1 not taken.
1191891 const_cond = make_cond_for_table(thd, cond, join->const_table_map,
9387 table_map(0), true);
9388
9389 // Add conditions added by add_not_null_conds()
9390
2/2
✓ Branch 0 taken 90074 times.
✓ Branch 1 taken 1816622 times.
1906696 for (uint i = 0; i < join->const_tables; i++) {
9391
2/4
✓ Branch 0 taken 90074 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 90074 times.
90074 if (and_conditions(&const_cond, join->best_ref[i]->condition()))
9392 return true;
9393 }
9394
3/6
✓ Branch 0 taken 1816624 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 1816598 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1816622 DBUG_EXECUTE("where",
9395 print_where(thd, const_cond, "constants", QT_ORDINARY););
9396
4/4
✓ Branch 0 taken 84423 times.
✓ Branch 1 taken 1732114 times.
✓ Branch 2 taken 84423 times.
✓ Branch 3 taken 1732114 times.
1900960 if (const_cond != nullptr &&
9397
2/4
✓ Branch 0 taken 84423 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84423 times.
✗ Branch 3 not taken.
84423 evaluate_during_optimization(const_cond, join->query_block)) {
9398
1/2
✓ Branch 0 taken 84423 times.
✗ Branch 1 not taken.
84423 const bool const_cond_result = const_cond->val_int() != 0;
9399
3/4
✓ Branch 0 taken 84423 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 84421 times.
86429 if (thd->is_error()) return true;
9400
9401
1/2
✓ Branch 0 taken 84421 times.
✗ Branch 1 not taken.
84421 Opt_trace_object trace_const_cond(trace);
9402 168842 trace_const_cond.add("condition_on_constant_tables", const_cond)
9403
2/4
✓ Branch 0 taken 84421 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84421 times.
✗ Branch 3 not taken.
84421 .add("condition_value", const_cond_result);
9404
2/2
✓ Branch 0 taken 82415 times.
✓ Branch 1 taken 2006 times.
84421 if (const_cond_result) {
9405 /*
9406 If all the tables referred by the condition are const tables and
9407 if the condition is not expensive, we can remove the where condition
9408 as it will always evaluate to "true".
9409 */
9410 82415 if (join->plan_is_const() &&
9411
7/8
✓ Branch 0 taken 76490 times.
✓ Branch 1 taken 5925 times.
✓ Branch 2 taken 76490 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 76487 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 76486 times.
✓ Branch 7 taken 5929 times.
158902 !(cond->used_tables() & ~join->const_table_map) &&
9412
3/4
✓ Branch 0 taken 76487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76486 times.
✓ Branch 3 taken 1 times.
76487 !cond->is_expensive()) {
9413
3/8
✓ Branch 0 taken 76486 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76486 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 76486 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
76486 DBUG_PRINT("info", ("Found always true WHERE condition"));
9414 76486 join->where_cond = nullptr;
9415 }
9416 } else {
9417
3/8
✓ Branch 0 taken 2006 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2006 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2006 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2006 DBUG_PRINT("info", ("Found impossible WHERE condition"));
9418 2006 return true;
9419 }
9420
2/2
✓ Branch 0 taken 82415 times.
✓ Branch 1 taken 2006 times.
84421 }
9421
9422 /*
9423 Extract remaining conditions from WHERE clause and join conditions,
9424 and attach them to the most appropriate table condition. This means that
9425 a condition will be evaluated as soon as all fields it depends on are
9426 available. For outer join conditions, the additional criterion is that
9427 we must have determined whether outer-joined rows are available, or
9428 have been NULL-extended, see JOIN::attach_join_conditions() for details.
9429 */
9430 {
9431
1/2
✓ Branch 0 taken 1814544 times.
✗ Branch 1 not taken.
1814529 Opt_trace_object trace_wrapper(trace);
9432
1/2
✓ Branch 0 taken 1814622 times.
✗ Branch 1 not taken.
1814544 Opt_trace_object trace_conditions(trace, "attaching_conditions_to_tables");
9433
1/2
✓ Branch 0 taken 1814605 times.
✗ Branch 1 not taken.
1814622 trace_conditions.add("original_condition", cond);
9434 Opt_trace_array trace_attached_comp(trace,
9435
1/2
✓ Branch 0 taken 1814618 times.
✗ Branch 1 not taken.
1814605 "attached_conditions_computation");
9436
9437
2/2
✓ Branch 0 taken 6165099 times.
✓ Branch 1 taken 1814715 times.
7979814 for (uint i = join->const_tables; i < join->tables; i++) {
9438 6165099 JOIN_TAB *const tab = join->best_ref[i];
9439
9440
2/2
✓ Branch 0 taken 2385461 times.
✓ Branch 1 taken 3779773 times.
6165099 if (!tab->position()) continue;
9441 /*
9442 first_inner is the X in queries like:
9443 SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
9444 */
9445 3779773 const plan_idx first_inner = tab->first_inner();
9446 3779818 const table_map used_tables = tab->prefix_tables();
9447 3779818 const table_map current_map = tab->added_tables();
9448 3779830 Item *tmp = nullptr;
9449
9450
2/2
✓ Branch 0 taken 3146705 times.
✓ Branch 1 taken 633125 times.
3779830 if (cond)
9451
1/2
✓ Branch 0 taken 3146674 times.
✗ Branch 1 not taken.
3146705 tmp = make_cond_for_table(thd, cond, used_tables, current_map, false);
9452 /* Add conditions added by add_not_null_conds(). */
9453
2/4
✓ Branch 0 taken 3779715 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3779715 times.
3779802 if (and_conditions(&tmp, tab->condition())) return true;
9454
9455
8/8
✓ Branch 0 taken 3146645 times.
✓ Branch 1 taken 633070 times.
✓ Branch 2 taken 987690 times.
✓ Branch 3 taken 2158955 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 987745 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 3779770 times.
3779715 if (cond && !tmp && tab->range_scan()) { // Outer join
9456
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 assert(tab->type() == JT_RANGE || tab->type() == JT_INDEX_MERGE);
9457 /*
9458 Hack to handle the case where we only refer to a table
9459 in the ON part of an OUTER JOIN. In this case we want the code
9460 below to check if we should use 'quick' instead.
9461 */
9462
3/8
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2 DBUG_PRINT("info", ("Item_func_true"));
9463
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 tmp = new Item_func_true(); // Always true
9464 }
9465
5/6
✓ Branch 0 taken 987693 times.
✓ Branch 1 taken 633109 times.
✓ Branch 2 taken 984967 times.
✓ Branch 3 taken 2726 times.
✓ Branch 4 taken 985005 times.
✗ Branch 5 not taken.
2605803 if (tmp || !cond || tab->type() == JT_REF ||
9466
8/8
✓ Branch 0 taken 1620802 times.
✓ Branch 1 taken 2158970 times.
✓ Branch 2 taken 473075 times.
✓ Branch 3 taken 511924 times.
✓ Branch 4 taken 15283 times.
✓ Branch 5 taken 457792 times.
✓ Branch 6 taken 3322010 times.
✓ Branch 7 taken 457790 times.
6385575 tab->type() == JT_REF_OR_NULL || tab->type() == JT_EQ_REF ||
9467 first_inner != NO_PLAN_IDX) {
9468
4/6
✓ Branch 0 taken 3321972 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 3321946 times.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
3322010 DBUG_EXECUTE("where",
9469 print_where(thd, tmp, tab->table()->alias, QT_ORDINARY););
9470 /*
9471 If tab is an inner table of an outer join operation,
9472 add a match guard to the pushed down predicate.
9473 The guard will turn the predicate on only after
9474 the first match for outer tables is encountered.
9475 */
9476
4/4
✓ Branch 0 taken 2688845 times.
✓ Branch 1 taken 633128 times.
✓ Branch 2 taken 2158916 times.
✓ Branch 3 taken 529929 times.
3321973 if (cond && tmp) {
9477 /*
9478 Because of GroupIndexSkipScanIterator there may be a select without
9479 a cond, so neutralize the hack above.
9480 */
9481
2/4
✓ Branch 0 taken 2158822 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2158822 times.
2158916 if (!(tmp = add_found_match_trig_cond(join, first_inner, tmp,
9482 NO_PLAN_IDX)))
9483 return true;
9484 2158822 tab->set_condition(tmp);
9485 } else {
9486 1163057 tab->set_condition(nullptr);
9487 }
9488
9489
4/6
✓ Branch 0 taken 3321964 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 3321938 times.
✓ Branch 4 taken 26 times.
✗ Branch 5 not taken.
3321983 DBUG_EXECUTE("where",
9490 print_where(thd, tmp, tab->table()->alias, QT_ORDINARY););
9491
9492
2/2
✓ Branch 0 taken 33913 times.
✓ Branch 1 taken 3288078 times.
3321964 if (tab->range_scan()) {
9493
3/6
✓ Branch 0 taken 33913 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33913 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 33913 times.
33913 if (tab->needed_reg.is_clear_all() && tab->type() != JT_CONST) {
9494 /*
9495 We keep (for now) the QUICK AM calculated in
9496 get_quick_record_count().
9497 */
9498 } else {
9499 destroy(tab->range_scan());
9500 tab->set_range_scan(nullptr);
9501 }
9502 }
9503
9504
4/4
✓ Branch 0 taken 1989012 times.
✓ Branch 1 taken 33041 times.
✓ Branch 2 taken 1988149 times.
✓ Branch 3 taken 872 times.
7333082 if ((tab->type() == JT_ALL || tab->type() == JT_RANGE ||
9505
6/6
✓ Branch 0 taken 2022070 times.
✓ Branch 1 taken 1299918 times.
✓ Branch 2 taken 49440 times.
✓ Branch 3 taken 1938726 times.
✓ Branch 4 taken 1382254 times.
✓ Branch 5 taken 1939743 times.
8682420 tab->type() == JT_INDEX_MERGE || tab->type() == JT_INDEX_SCAN) &&
9506
2/2
✓ Branch 0 taken 1382254 times.
✓ Branch 1 taken 1017 times.
1383271 tab->use_quick != QS_RANGE) {
9507 /*
9508 We plan to scan (table/index/range scan).
9509 Check again if we should use an index. We can use an index if:
9510
9511 1a) There is a condition that range optimizer can work on, and
9512 1b) There are non-constant conditions on one or more keys, and
9513 1c) Some of the non-constant fields may have been read
9514 already. This may be the case if this is not the first
9515 table in the join OR this is a subselect with
9516 non-constant conditions referring to an outer table
9517 (dependent subquery)
9518 or,
9519 2a) There are conditions only relying on constants
9520 2b) This is the first non-constant table
9521 2c) There is a limit of rows to read that is lower than
9522 the fanout for this table, predicate filters included
9523 (i.e., the estimated number of rows that will be
9524 produced for this table per row combination of
9525 previous tables)
9526 2d) The query is NOT run with FOUND_ROWS() (because in that
9527 case we have to scan through all rows to count them anyway)
9528 */
9529 enum {
9530 DONT_RECHECK,
9531 NOT_FIRST_TABLE,
9532 LOW_LIMIT
9533 1382254 } recheck_reason = DONT_RECHECK;
9534
9535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1382254 times.
1382254 assert(tab->const_keys.is_subset(tab->keys()));
9536
9537 1382254 const join_type orig_join_type = tab->type();
9538 1382254 const AccessPath *const orig_range_scan = tab->range_scan();
9539
9540
2/2
✓ Branch 0 taken 60293 times.
✓ Branch 1 taken 688873 times.
749166 if (cond && // 1a
9541
6/6
✓ Branch 0 taken 749166 times.
✓ Branch 1 taken 633088 times.
✓ Branch 2 taken 4610 times.
✓ Branch 3 taken 55683 times.
✓ Branch 4 taken 56189 times.
✓ Branch 5 taken 1326065 times.
2136030 (tab->keys() != tab->const_keys) && // 1b
9542 4610 (i > 0 || // 1c
9543
2/2
✓ Branch 0 taken 776 times.
✓ Branch 1 taken 3834 times.
4610 (join->query_block->master_query_expression()->item &&
9544
3/4
✓ Branch 0 taken 776 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 506 times.
✓ Branch 3 taken 270 times.
776 cond->is_outer_reference())))
9545 56189 recheck_reason = NOT_FIRST_TABLE;
9546 1326065 else if (!tab->const_keys.is_clear_all() && // 2a
9547
2/2
✓ Branch 0 taken 240568 times.
✓ Branch 1 taken 894 times.
241462 i == join->const_tables && // 2b
9548 240568 (join->query_expression()->select_limit_cnt <
9549 240568 (tab->position()->rows_fetched *
9550
6/6
✓ Branch 0 taken 241462 times.
✓ Branch 1 taken 1084603 times.
✓ Branch 2 taken 2748 times.
✓ Branch 3 taken 237820 times.
✓ Branch 4 taken 2743 times.
✓ Branch 5 taken 1323322 times.
1570275 tab->position()->filter_effect)) && // 2c
9551
2/2
✓ Branch 0 taken 2743 times.
✓ Branch 1 taken 5 times.
2748 !join->calc_found_rows) // 2d
9552 2743 recheck_reason = LOW_LIMIT;
9553
9554 // Don't recheck if the storage engine does not support index access.
9555
2/2
✓ Branch 0 taken 308 times.
✓ Branch 1 taken 1381946 times.
1382254 if ((tab->table()->file->ha_table_flags() & HA_NO_INDEX_ACCESS) != 0)
9556 308 recheck_reason = DONT_RECHECK;
9557
9558
2/2
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 1382068 times.
1382254 if (tab->position()->sj_strategy == SJ_OPT_LOOSE_SCAN) {
9559 /*
9560 Semijoin loose scan has settled for a certain index-based access
9561 method with suitable characteristics, don't substitute it.
9562 */
9563 186 recheck_reason = DONT_RECHECK;
9564 }
9565
9566
2/2
✓ Branch 0 taken 58894 times.
✓ Branch 1 taken 1323360 times.
1382254 if (recheck_reason != DONT_RECHECK) {
9567
1/2
✓ Branch 0 taken 58894 times.
✗ Branch 1 not taken.
58894 Opt_trace_object trace_one_table(trace);
9568
1/2
✓ Branch 0 taken 58894 times.
✗ Branch 1 not taken.
58894 trace_one_table.add_utf8_table(tab->table_ref);
9569
1/2
✓ Branch 0 taken 58894 times.
✗ Branch 1 not taken.
58894 Opt_trace_object trace_table(trace, "rechecking_index_usage");
9570
2/2
✓ Branch 0 taken 56151 times.
✓ Branch 1 taken 2743 times.
58894 if (recheck_reason == NOT_FIRST_TABLE)
9571
1/2
✓ Branch 0 taken 56151 times.
✗ Branch 1 not taken.
56151 trace_table.add_alnum("recheck_reason", "not_first_table");
9572 else
9573
1/2
✓ Branch 0 taken 2743 times.
✗ Branch 1 not taken.
2743 trace_table.add_alnum("recheck_reason", "low_limit")
9574
1/2
✓ Branch 0 taken 2743 times.
✗ Branch 1 not taken.
2743 .add("limit", join->query_expression()->select_limit_cnt)
9575 2743 .add("row_estimate", tab->position()->rows_fetched *
9576
1/2
✓ Branch 0 taken 2743 times.
✗ Branch 1 not taken.
2743 tab->position()->filter_effect);
9577
9578 /* Join with outer join condition */
9579 58894 Item *orig_cond = tab->condition();
9580
1/2
✓ Branch 0 taken 58894 times.
✗ Branch 1 not taken.
58894 tab->and_with_condition(tab->join_cond());
9581
9582 /*
9583 We can't call sel->cond->fix_fields,
9584 as it will break tab->join_cond() if it's AND condition
9585 (fix_fields currently removes extra AND/OR levels).
9586 Yet attributes of the just built condition are not needed.
9587 Thus we call sel->cond->quick_fix_field for safety.
9588 */
9589
4/6
✓ Branch 0 taken 58327 times.
✓ Branch 1 taken 567 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 58327 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 58894 times.
58894 if (tab->condition() && !tab->condition()->fixed)
9590 tab->condition()->quick_fix_field();
9591
9592 58894 Key_map usable_keys = tab->keys();
9593 58894 enum_order interesting_order = ORDER_NOT_RELEVANT;
9594
9595
2/2
✓ Branch 0 taken 2743 times.
✓ Branch 1 taken 56151 times.
58894 if (recheck_reason == LOW_LIMIT) {
9596 2743 int read_direction = 0;
9597
9598 /*
9599 If the current plan is to use range, then check if the
9600 already selected index provides the order dictated by the
9601 ORDER BY clause.
9602 */
9603
6/6
✓ Branch 0 taken 1474 times.
✓ Branch 1 taken 1269 times.
✓ Branch 2 taken 1472 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1472 times.
✓ Branch 5 taken 1271 times.
4217 if (tab->range_scan() &&
9604 1474 used_index(tab->range_scan()) != MAX_KEY) {
9605 1472 const uint ref_key = used_index(tab->range_scan());
9606 bool skip_quick;
9607
1/2
✓ Branch 0 taken 1472 times.
✗ Branch 1 not taken.
1472 read_direction = test_if_order_by_key(
9608 &join->order, tab->table(), ref_key, nullptr, &skip_quick);
9609
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1472 times.
1472 if (skip_quick) read_direction = 0;
9610 /*
9611 If the index provides order there is no need to recheck
9612 index usage; we already know from the former call to
9613 test_quick_select() that a range scan on the chosen
9614 index is cheapest. Note that previous calls to
9615 test_quick_select() did not take order direction
9616 (ASC/DESC) into account, so in case of DESC ordering
9617 we still need to recheck.
9618 */
9619
4/4
✓ Branch 0 taken 767 times.
✓ Branch 1 taken 705 times.
✓ Branch 2 taken 705 times.
✓ Branch 3 taken 767 times.
2239 if (read_direction == 1 ||
9620
3/4
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 448 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 319 times.
1086 (read_direction == -1 &&
9621 319 is_reverse_sorted_range(tab->range_scan()))) {
9622 705 recheck_reason = DONT_RECHECK;
9623 }
9624 }
9625 // We do a cost based search for an ordering index here. Do this
9626 // only if prefer_ordering_index switch is on or an index is
9627 // forced for order by
9628
4/4
✓ Branch 0 taken 2038 times.
✓ Branch 1 taken 705 times.
✓ Branch 2 taken 2036 times.
✓ Branch 3 taken 707 times.
4781 if (recheck_reason != DONT_RECHECK &&
9629
4/4
✓ Branch 0 taken 2036 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2034 times.
✓ Branch 3 taken 2 times.
4074 (tab->table()->force_index_order ||
9630 2036 thd->optimizer_switch_flag(
9631 OPTIMIZER_SWITCH_PREFER_ORDERING_INDEX))) {
9632 2036 int best_key = -1;
9633 ha_rows select_limit =
9634 2036 join->query_expression()->select_limit_cnt;
9635
9636 /* Use index specified in FORCE INDEX FOR ORDER BY, if any. */
9637
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2034 times.
2036 if (tab->table()->force_index_order)
9638 2 usable_keys.intersect(tab->table()->keys_in_use_for_order_by);
9639
9640 // Do a cost based search on the indexes that give sort order.
9641
1/2
✓ Branch 0 taken 2036 times.
✗ Branch 1 not taken.
2036 test_if_cheaper_ordering(
9642 tab, &join->order, tab->table(), usable_keys, -1,
9643 select_limit, &best_key, &read_direction, &select_limit);
9644
2/2
✓ Branch 0 taken 1100 times.
✓ Branch 1 taken 936 times.
2036 if (best_key < 0)
9645 1100 recheck_reason = DONT_RECHECK; // No usable keys
9646 else {
9647 // Only usable_key is the best_key chosen
9648 936 usable_keys.clear_all();
9649 936 usable_keys.set_bit(best_key);
9650 936 interesting_order =
9651
2/2
✓ Branch 0 taken 376 times.
✓ Branch 1 taken 560 times.
936 (read_direction == -1 ? ORDER_DESC : ORDER_ASC);
9652 }
9653 }
9654 }
9655
9656 58894 bool search_if_impossible = recheck_reason != DONT_RECHECK;
9657
2/2
✓ Branch 0 taken 57089 times.
✓ Branch 1 taken 1805 times.
58894 if (search_if_impossible) {
9658
2/2
✓ Branch 0 taken 412 times.
✓ Branch 1 taken 56677 times.
57089 if (tab->range_scan()) {
9659 412 destroy(tab->range_scan());
9660 412 tab->set_type(JT_ALL);
9661 }
9662 AccessPath *range_scan;
9663 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
9664 57089 thd->variables.range_alloc_block_size);
9665 57089 search_if_impossible =
9666 114178 test_quick_select(
9667 thd, thd->mem_root, &temp_mem_root, usable_keys,
9668
1/2
✓ Branch 0 taken 57089 times.
✗ Branch 1 not taken.
57089 used_tables & ~tab->table_ref->map(), 0,
9669
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57089 times.
57089 join->calc_found_rows
9670 ? HA_POS_ERROR
9671 57089 : join->query_expression()->select_limit_cnt,
9672 false, // don't force quick range
9673 interesting_order, tab->table(),
9674 57089 tab->skip_records_in_range(), tab->condition(),
9675 57089 &tab->needed_reg, tab->table()->force_index,
9676 57089 join->query_block, &range_scan) < 0;
9677 57089 tab->set_range_scan(range_scan);
9678 57089 }
9679 58894 tab->set_condition(orig_cond);
9680
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 58891 times.
58894 if (search_if_impossible) {
9681 /*
9682 Before reporting "Impossible WHERE" for the whole query
9683 we have to check isn't it only "impossible ON" instead
9684 */
9685
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!tab->join_cond())
9686 3 return true; // No ON, so it's really "impossible WHERE"
9687 Opt_trace_object trace_without_on(trace, "without_ON_clause");
9688 if (tab->range_scan()) {
9689 destroy(tab->range_scan());
9690 tab->set_type(JT_ALL);
9691 }
9692 AccessPath *range_scan;
9693 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
9694 thd->variables.range_alloc_block_size);
9695 const bool impossible_where =
9696 test_quick_select(
9697 thd, thd->mem_root, &temp_mem_root, tab->keys(),
9698 used_tables & ~tab->table_ref->map(), 0,
9699 join->calc_found_rows
9700 ? HA_POS_ERROR
9701 : join->query_expression()->select_limit_cnt,
9702 false, // don't force quick range
9703 ORDER_NOT_RELEVANT, tab->table(),
9704 tab->skip_records_in_range(), tab->condition(),
9705 &tab->needed_reg, tab->table()->force_index,
9706 join->query_block, &range_scan) < 0;
9707 tab->set_range_scan(range_scan);
9708 if (impossible_where) return true; // Impossible WHERE
9709 }
9710
9711 /*
9712 Access method changed. This is after deciding join order
9713 and access method for all other tables so the info
9714 updated below will not have any effect on the execution
9715 plan.
9716 */
9717
2/2
✓ Branch 0 taken 1764 times.
✓ Branch 1 taken 57127 times.
58891 if (tab->range_scan())
9718
1/2
✓ Branch 0 taken 1764 times.
✗ Branch 1 not taken.
1764 tab->set_type(calc_join_type(tab->range_scan()));
9719
9720
4/4
✓ Branch 0 taken 58891 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 58891 times.
✓ Branch 3 taken 3 times.
58897 } // end of "if (recheck_reason != DONT_RECHECK)"
9721
9722
4/4
✓ Branch 0 taken 1359488 times.
✓ Branch 1 taken 22763 times.
✓ Branch 2 taken 23374 times.
✓ Branch 3 taken 1358877 times.
2741739 if (!tab->table()->quick_keys.is_subset(tab->checked_keys) ||
9723
2/2
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 1358877 times.
1359488 !tab->needed_reg.is_subset(tab->checked_keys)) {
9724 23374 tab->keys().merge(tab->table()->quick_keys);
9725 23374 tab->keys().merge(tab->needed_reg);
9726
9727 /*
9728 The logic below for assigning tab->use_quick is strange.
9729 It bases the decision of which access method to use
9730 (dynamic range, range, scan) based on seemingly
9731 unrelated information like the presence of another index
9732 with too bad selectivity to be used.
9733
9734 Consider the following scenario:
9735
9736 The join optimizer has decided to use join order
9737 (t1,t2), and 'tab' is currently t2. Further, assume that
9738 there is a join condition between t1 and t2 using some
9739 range operator (e.g. "t1.x < t2.y").
9740
9741 It has been decided that a table scan is best for t2.
9742 make_join_query_block() then reran the range optimizer a few
9743 lines up because there is an index 't2.good_idx'
9744 covering the t2.y column. If 'good_idx' is the only
9745 index in t2, the decision below will be to use dynamic
9746 range. However, if t2 also has another index 't2.other'
9747 which the range access method can be used on but
9748 selectivity is bad (#rows estimate is high), then table
9749 scan is chosen instead.
9750
9751 Thus, the choice of DYNAMIC RANGE vs SCAN depends on the
9752 presence of an index that has so bad selectivity that it
9753 will not be used anyway.
9754 */
9755
6/6
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 22745 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 611 times.
✓ Branch 4 taken 611 times.
✓ Branch 5 taken 22763 times.
24021 if (!tab->needed_reg.is_clear_all() &&
9756
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
647 (tab->table()->quick_keys.is_clear_all() ||
9757 18 (tab->range_scan() &&
9758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 (tab->range_scan()->num_output_rows >= 100.0)))) {
9759 611 tab->use_quick = QS_DYNAMIC_RANGE;
9760 611 tab->set_type(JT_ALL);
9761 } else
9762 22763 tab->use_quick = QS_RANGE;
9763 }
9764
9765
6/6
✓ Branch 0 taken 1381737 times.
✓ Branch 1 taken 514 times.
✓ Branch 2 taken 401 times.
✓ Branch 3 taken 1381336 times.
✓ Branch 4 taken 915 times.
✓ Branch 5 taken 1381336 times.
2763988 if (tab->type() != orig_join_type ||
9766 1381737 tab->range_scan() != orig_range_scan) // Access method changed
9767 915 tab->position()->filter_effect = COND_FILTER_STALE;
9768 }
9769 }
9770
9771
2/4
✓ Branch 0 taken 3779735 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3779735 times.
3779784 if (join->attach_join_conditions(i)) return true;
9772 }
9773
1/2
✓ Branch 0 taken 1814608 times.
✗ Branch 1 not taken.
1814715 trace_attached_comp.end();
9774
9775 /*
9776 In outer joins the loop above, in iteration for table #i, may push
9777 conditions to a table before #i. Thus, the processing below has to be in
9778 a separate loop:
9779 */
9780 Opt_trace_array trace_attached_summary(trace,
9781
1/2
✓ Branch 0 taken 1814618 times.
✗ Branch 1 not taken.
1814608 "attached_conditions_summary");
9782
2/2
✓ Branch 0 taken 6165142 times.
✓ Branch 1 taken 1814716 times.
7979858 for (uint i = join->const_tables; i < join->tables; i++) {
9783 6165142 JOIN_TAB *const tab = join->best_ref[i];
9784
2/2
✓ Branch 0 taken 2385460 times.
✓ Branch 1 taken 3779772 times.
6165142 if (!tab->table()) continue;
9785 3779772 Item *const tab_cond = tab->condition();
9786
1/2
✓ Branch 0 taken 3779796 times.
✗ Branch 1 not taken.
3779801 Opt_trace_object trace_one_table(trace);
9787
2/4
✓ Branch 0 taken 3779794 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3779791 times.
✗ Branch 3 not taken.
3779796 trace_one_table.add_utf8_table(tab->table_ref).add("attached", tab_cond);
9788
6/6
✓ Branch 0 taken 2687776 times.
✓ Branch 1 taken 1092015 times.
✓ Branch 2 taken 12887 times.
✓ Branch 3 taken 2674896 times.
✓ Branch 4 taken 12887 times.
✓ Branch 5 taken 3766911 times.
3779791 if (tab_cond && tab_cond->has_subquery()) // traverse only if needed
9789 {
9790 /*
9791 Why we pass walk_subquery=false: imagine
9792 WHERE t1.col IN (SELECT * FROM t2
9793 WHERE t2.col IN (SELECT * FROM t3)
9794 and tab==t1. The grandchild subquery (SELECT * FROM t3) should not
9795 be marked as "in condition of t1" but as "in condition of t2", for
9796 correct calculation of the number of its executions.
9797 */
9798 12887 std::pair<Query_block *, int> pair_object(join->query_block, i);
9799
1/2
✓ Branch 0 taken 12887 times.
✗ Branch 1 not taken.
12887 tab_cond->walk(&Item::inform_item_in_cond_of_tab, enum_walk::POSTFIX,
9800 pointer_cast<uchar *>(&pair_object));
9801 }
9802 3779798 }
9803
6/6
✓ Branch 0 taken 1814613 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1814625 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1814624 times.
✓ Branch 5 taken 2 times.
1814736 }
9804 1814624 return false;
9805 1816634 }
9806
9807 /**
9808 Remove the following expressions from ORDER BY and GROUP BY:
9809 Constant expressions @n
9810 Expression that only uses tables that are of type EQ_REF and the reference
9811 is in the ORDER list or if all refereed tables are of the above type.
9812
9813 In the following, the X field can be removed:
9814 @code
9815 SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
9816 SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
9817 @endcode
9818
9819 These can't be optimized:
9820 @code
9821 SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
9822 SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
9823 SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
9824 @endcode
9825
9826 @param join join object
9827 @param start_order clause being analyzed (ORDER BY, GROUP BY...)
9828 @param tab table
9829 @param cached_eq_ref_tables bitmap: bit Z is set if the table of map Z
9830 was already the subject of an eq_ref_table() call for the same clause; then
9831 the return value of this previous call can be found at bit Z of
9832 'eq_ref_tables'
9833 @param eq_ref_tables see above.
9834 */
9835
9836 376218 static bool eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab,
9837 table_map *cached_eq_ref_tables,
9838 table_map *eq_ref_tables) {
9839 /* We can skip const tables only if not an outer table */
9840
6/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 376208 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 376217 times.
376218 if (tab->type() == JT_CONST && tab->first_inner() == NO_PLAN_IDX) return true;
9841
6/6
✓ Branch 0 taken 104936 times.
✓ Branch 1 taken 271281 times.
✓ Branch 2 taken 235 times.
✓ Branch 3 taken 104701 times.
✓ Branch 4 taken 271516 times.
✓ Branch 5 taken 104701 times.
376217 if (tab->type() != JT_EQ_REF || tab->table()->is_nullable()) return false;
9842
9843 104701 const table_map map = tab->table_ref->map();
9844 104701 uint found = 0;
9845
9846 104755 for (Item **ref_item = tab->ref().items,
9847 104701 **end = ref_item + tab->ref().key_parts;
9848
2/2
✓ Branch 0 taken 104702 times.
✓ Branch 1 taken 53 times.
104755 ref_item != end; ref_item++) {
9849
1/2
✓ Branch 0 taken 104702 times.
✗ Branch 1 not taken.
104702 if (!(*ref_item)->const_item()) { // Not a const ref
9850 ORDER *order;
9851
2/2
✓ Branch 0 taken 290797 times.
✓ Branch 1 taken 104651 times.
395448 for (order = start_order; order; order = order->next) {
9852
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 290746 times.
290797 if ((*ref_item)->eq(order->item[0], false)) break;
9853 }
9854
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 104651 times.
104702 if (order) {
9855
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 1 times.
51 if (!(order->used & map)) {
9856 50 found++;
9857 50 order->used |= map;
9858 }
9859 51 continue; // Used in ORDER BY
9860 }
9861
2/2
✓ Branch 0 taken 104648 times.
✓ Branch 1 taken 3 times.
104651 if (!only_eq_ref_tables(join, start_order, (*ref_item)->used_tables(),
9862 cached_eq_ref_tables, eq_ref_tables))
9863 104648 return false;
9864 }
9865 }
9866 /* Check that there was no reference to table before sort order */
9867
3/4
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 86 times.
✗ Branch 3 not taken.
96 for (; found && start_order; start_order = start_order->next) {
9868
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 79 times.
86 if (start_order->used & map) {
9869 7 found--;
9870 7 continue;
9871 }
9872
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 36 times.
79 if (start_order->depend_map & map) return false;
9873 }
9874 10 return true;
9875 }
9876
9877 /// @see eq_ref_table()
9878 486003 static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables,
9879 table_map *cached_eq_ref_tables,
9880 table_map *eq_ref_tables) {
9881 486003 tables &= ~PSEUDO_TABLE_BITS;
9882
2/2
✓ Branch 0 taken 667059 times.
✓ Branch 1 taken 11 times.
667070 for (JOIN_TAB **tab = join->map2table; tables; tab++, tables >>= 1) {
9883
2/2
✓ Branch 0 taken 486003 times.
✓ Branch 1 taken 181056 times.
667059 if (tables & 1) {
9884 486003 const table_map map = (*tab)->table_ref->map();
9885 bool is_eq_ref;
9886
2/2
✓ Branch 0 taken 109785 times.
✓ Branch 1 taken 376218 times.
486003 if (*cached_eq_ref_tables & map) // then there exists a cached bit
9887 109785 is_eq_ref = *eq_ref_tables & map;
9888 else {
9889 376218 is_eq_ref = eq_ref_table(join, order, *tab, cached_eq_ref_tables,
9890 eq_ref_tables);
9891
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 376207 times.
376218 if (is_eq_ref)
9892 11 *eq_ref_tables |= map;
9893 else
9894 376207 *eq_ref_tables &= ~map;
9895 376218 *cached_eq_ref_tables |= map; // now there exists a cached bit
9896 }
9897
2/2
✓ Branch 0 taken 485992 times.
✓ Branch 1 taken 11 times.
486003 if (!is_eq_ref) return false;
9898 }
9899 }
9900 11 return true;
9901 }
9902
9903 /**
9904 Check if an expression in ORDER BY or GROUP BY is a duplicate of a
9905 preceding expression.
9906
9907 @param first_order the first expression in the ORDER BY or
9908 GROUP BY clause
9909 @param possible_dup the expression that might be a duplicate of
9910 another expression preceding it the ORDER BY
9911 or GROUP BY clause
9912
9913 @returns true if possible_dup is a duplicate, false otherwise
9914 */
9915 892910 static bool duplicate_order(const ORDER *first_order,
9916 const ORDER *possible_dup) {
9917 const ORDER *order;
9918
1/2
✓ Branch 0 taken 2468077 times.
✗ Branch 1 not taken.
2468077 for (order = first_order; order; order = order->next) {
9919
2/2
✓ Branch 0 taken 892765 times.
✓ Branch 1 taken 1575312 times.
2468077 if (order == possible_dup) {
9920 // all expressions preceding possible_dup have been checked.
9921 892765 return false;
9922 } else {
9923 1575312 const Item *it1 = order->item[0]->real_item();
9924 1575312 const Item *it2 = possible_dup->item[0]->real_item();
9925
9926
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 1575167 times.
1575312 if (it1->eq(it2, false)) return true;
9927 }
9928 }
9929 return false;
9930 }
9931
9932 /**
9933 Remove all constants and check if ORDER only contains simple
9934 expressions.
9935
9936 simple_order is set to true if sort_order only uses fields from head table
9937 and the head table is not a LEFT JOIN table.
9938
9939 @param first_order List of GROUP BY or ORDER BY sub-clauses.
9940 @param cond WHERE condition.
9941 @param change If true, remove sub-clauses that need not be evaluated.
9942 If this is not set, then only simple_order is calculated.
9943 @param[out] simple_order Set to true if we are only using simple expressions.
9944 @param group_by True if first_order represents a grouping operation.
9945
9946 @returns new sort order, after const elimination (when change is true).
9947 */
9948
9949 3628998 ORDER *JOIN::remove_const(ORDER *first_order, Item *cond, bool change,
9950 bool *simple_order, bool group_by) {
9951
1/2
✓ Branch 0 taken 3629209 times.
✗ Branch 1 not taken.
3628998 DBUG_TRACE;
9952
9953
3/6
✓ Branch 0 taken 3629213 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3629217 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3629217 times.
✗ Branch 5 not taken.
3629209 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
9954
9955
2/2
✓ Branch 0 taken 164752 times.
✓ Branch 1 taken 3464464 times.
3629213 if (plan_is_const())
9956
2/2
✓ Branch 0 taken 164744 times.
✓ Branch 1 taken 8 times.
164752 return change ? nullptr : first_order; // No need to sort
9957
9958 3464464 Opt_trace_context *const trace = &thd->opt_trace;
9959
1/2
✓ Branch 0 taken 3464457 times.
✗ Branch 1 not taken.
3464464 Opt_trace_disable_I_S trace_disabled(trace, first_order == nullptr);
9960 Opt_trace_object trace_simpl(
9961
3/4
✓ Branch 0 taken 1732216 times.
✓ Branch 1 taken 1732241 times.
✓ Branch 2 taken 3464456 times.
✗ Branch 3 not taken.
3464457 trace, group_by ? "simplifying_group_by" : "simplifying_order_by");
9962
2/2
✓ Branch 0 taken 5256 times.
✓ Branch 1 taken 3459193 times.
3464456 if (trace->is_started()) {
9963 5256 String str;
9964 5256 Query_block::print_order(
9965
1/2
✓ Branch 0 taken 5256 times.
✗ Branch 1 not taken.
5256 thd, &str, first_order,
9966 enum_query_type(QT_TO_SYSTEM_CHARSET | QT_SHOW_SELECT_NUMBER |
9967 QT_NO_DEFAULT_DB));
9968
1/2
✓ Branch 0 taken 5256 times.
✗ Branch 1 not taken.
5256 trace_simpl.add_utf8("original_clause", str.ptr(), str.length());
9969 5256 }
9970
1/2
✓ Branch 0 taken 3464428 times.
✗ Branch 1 not taken.
3464449 Opt_trace_array trace_each_item(trace, "items");
9971
9972 3464428 JOIN_TAB *const first_tab = best_ref[const_tables];
9973 3464428 table_map first_table = first_tab->table_ref->map();
9974 3464450 table_map not_const_tables = ~const_table_map;
9975 table_map ref;
9976 // Caches to avoid repeating eq_ref_table() calls, @see eq_ref_table()
9977 3464450 table_map eq_ref_tables = 0, cached_eq_ref_tables = 0;
9978
9979 3464450 ORDER **prev_ptr = &first_order;
9980 3464450 *simple_order = !first_tab->join_cond();
9981
9982 // De-optimization in conjunction with window functions
9983
4/4
✓ Branch 0 taken 1732214 times.
✓ Branch 1 taken 1732230 times.
✓ Branch 2 taken 1889 times.
✓ Branch 3 taken 1730325 times.
3464444 if (group_by && m_windows.elements > 0) *simple_order = false;
9984
9985
1/2
✓ Branch 0 taken 3464464 times.
✗ Branch 1 not taken.
3464444 update_depend_map(first_order);
9986
9987
2/2
✓ Branch 0 taken 893923 times.
✓ Branch 1 taken 3464464 times.
4358387 for (ORDER *order = first_order; order; order = order->next) {
9988
1/2
✓ Branch 0 taken 893923 times.
✗ Branch 1 not taken.
893923 Opt_trace_object trace_one_item(trace);
9989
1/2
✓ Branch 0 taken 893923 times.
✗ Branch 1 not taken.
893923 trace_one_item.add("item", order->item[0]);
9990
1/2
✓ Branch 0 taken 893923 times.
✗ Branch 1 not taken.
893923 table_map order_tables = order->item[0]->used_tables();
9991
9992
6/6
✓ Branch 0 taken 893574 times.
✓ Branch 1 taken 349 times.
✓ Branch 2 taken 893485 times.
✓ Branch 3 taken 89 times.
✓ Branch 4 taken 473 times.
✓ Branch 5 taken 893450 times.
1787408 if (order->item[0]->has_aggregation() || order->item[0]->has_wf() ||
9993 /*
9994 If the outer table of an outer join is const (either by itself or
9995 after applying WHERE condition), grouping on a field from such a
9996 table will be optimized away and filesort without temporary table
9997 will be used unless we prevent that now. Filesort is not fit to
9998 handle joins and the join condition is not applied. We can't detect
9999 the case without an expensive test, however, so we force temporary
10000 table for all queries containing more than one table, ROLLUP, and an
10001 outer join.
10002 */
10003
4/4
✓ Branch 0 taken 428070 times.
✓ Branch 1 taken 465415 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 427996 times.
893485 (primary_tables > 1 && rollup_state == RollupState::INITED &&
10004
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 39 times.
74 query_block->outer_join)) {
10005 473 *simple_order = false; // Must use a temporary table to sort
10006
4/4
✓ Branch 0 taken 542 times.
✓ Branch 1 taken 892908 times.
✓ Branch 2 taken 540 times.
✓ Branch 3 taken 892910 times.
893992 } else if ((order_tables & not_const_tables) == 0 &&
10007
3/4
✓ Branch 0 taken 542 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 540 times.
✓ Branch 3 taken 2 times.
542 evaluate_during_optimization(order->item[0], query_block)) {
10008
2/2
✓ Branch 0 taken 158 times.
✓ Branch 1 taken 382 times.
540 if (order->item[0]->has_subquery()) {
10009
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 20 times.
158 if (!thd->lex->is_explain()) {
10010
1/2
✓ Branch 0 taken 138 times.
✗ Branch 1 not taken.
138 Opt_trace_array trace_subselect(trace, "subselect_evaluation");
10011 138 String str;
10012
1/2
✓ Branch 0 taken 138 times.
✗ Branch 1 not taken.
138 order->item[0]->val_str(&str);
10013 138 }
10014
1/2
✓ Branch 0 taken 158 times.
✗ Branch 1 not taken.
158 order->item[0]->mark_subqueries_optimized_away();
10015 }
10016
1/2
✓ Branch 0 taken 540 times.
✗ Branch 1 not taken.
540 trace_one_item.add("uses_only_constant_tables", true);
10017 540 continue; // skip const item
10018
3/4
✓ Branch 0 taken 892910 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 892765 times.
893450 } else if (duplicate_order(first_order, order)) {
10019 /*
10020 If 'order' is a duplicate of an expression earlier in the
10021 ORDER/GROUP BY sequence, it can be removed from the ORDER BY
10022 or GROUP BY clause.
10023 */
10024
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 trace_one_item.add("duplicate_item", true);
10025 145 continue;
10026
6/6
✓ Branch 0 taken 859688 times.
✓ Branch 1 taken 33077 times.
✓ Branch 2 taken 58 times.
✓ Branch 3 taken 859630 times.
✓ Branch 4 taken 58 times.
✓ Branch 5 taken 892707 times.
892765 } else if (order->in_field_list && order->item[0]->has_subquery()) {
10027 /*
10028 If the order item is a subquery that is also in the field
10029 list, a temp table should be used to avoid evaluating the
10030 subquery for each row both when a) creating a sort index and
10031 b) getting the value.
10032 Example: "SELECT (SELECT ... ) as a ... GROUP BY a;"
10033 */
10034 58 *simple_order = false;
10035
2/2
✓ Branch 0 taken 341 times.
✓ Branch 1 taken 892366 times.
892707 } else if (order_tables & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)) {
10036 341 *simple_order = false;
10037 } else {
10038
7/8
✓ Branch 0 taken 548389 times.
✓ Branch 1 taken 343977 times.
✓ Branch 2 taken 548389 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15446 times.
✓ Branch 5 taken 532943 times.
✓ Branch 6 taken 15446 times.
✓ Branch 7 taken 876920 times.
892366 if (cond != nullptr && check_field_is_const(cond, order->item[0])) {
10039
1/2
✓ Branch 0 taken 15446 times.
✗ Branch 1 not taken.
15446 trace_one_item.add("equals_constant_in_where", true);
10040 15446 continue;
10041 }
10042
2/2
✓ Branch 0 taken 381526 times.
✓ Branch 1 taken 495394 times.
876920 if ((ref = order_tables & (not_const_tables ^ first_table))) {
10043
4/4
✓ Branch 0 taken 381352 times.
✓ Branch 1 taken 174 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 381518 times.
762878 if (!(order_tables & first_table) &&
10044
3/4
✓ Branch 0 taken 381352 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 381344 times.
381352 only_eq_ref_tables(this, first_order, ref, &cached_eq_ref_tables,
10045 &eq_ref_tables)) {
10046
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 trace_one_item.add("eq_ref_to_preceding_items", true);
10047 8 continue;
10048 }
10049 381518 *simple_order = false; // Must do a temp table to sort
10050 }
10051 }
10052
2/2
✓ Branch 0 taken 877195 times.
✓ Branch 1 taken 589 times.
877784 if (change) *prev_ptr = order; // use this entry
10053 877784 prev_ptr = &order->next;
10054
2/2
✓ Branch 0 taken 877784 times.
✓ Branch 1 taken 16139 times.
893923 }
10055
2/2
✓ Branch 0 taken 3463623 times.
✓ Branch 1 taken 841 times.
3464464 if (change) *prev_ptr = nullptr;
10056
2/2
✓ Branch 0 taken 2903486 times.
✓ Branch 1 taken 560978 times.
3464464 if (prev_ptr == &first_order) // Nothing to sort/group
10057 2903486 *simple_order = true;
10058
5/8
✓ Branch 0 taken 3464427 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3464451 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 52 times.
✓ Branch 5 taken 3464399 times.
✓ Branch 6 taken 52 times.
✗ Branch 7 not taken.
3464464 DBUG_PRINT("exit", ("simple_order: %d", (int)*simple_order));
10059
10060
1/2
✓ Branch 0 taken 3464431 times.
✗ Branch 1 not taken.
3464451 trace_each_item.end();
10061
1/2
✓ Branch 0 taken 3464439 times.
✗ Branch 1 not taken.
3464431 trace_simpl.add("resulting_clause_is_simple", *simple_order);
10062
6/6
✓ Branch 0 taken 5256 times.
✓ Branch 1 taken 3459186 times.
✓ Branch 2 taken 5250 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 5250 times.
✓ Branch 5 taken 3459192 times.
3464439 if (trace->is_started() && change) {
10063 5250 String str;
10064 5250 Query_block::print_order(
10065
1/2
✓ Branch 0 taken 5250 times.
✗ Branch 1 not taken.
5250 thd, &str, first_order,
10066 enum_query_type(QT_TO_SYSTEM_CHARSET | QT_SHOW_SELECT_NUMBER |
10067 QT_NO_DEFAULT_DB));
10068
1/2
✓ Branch 0 taken 5250 times.
✗ Branch 1 not taken.
5250 trace_simpl.add_utf8("resulting_clause", str.ptr(), str.length());
10069 5250 }
10070
10071 3464442 return first_order;
10072 3629194 }
10073
10074 /**
10075 Optimize conditions by
10076
10077 a) applying transitivity to build multiple equality predicates
10078 (MEP): if x=y and y=z the MEP x=y=z is built.
10079 b) apply constants where possible. If the value of x is known to be
10080 42, x is replaced with a constant of value 42. By transitivity, this
10081 also applies to MEPs, so the MEP in a) will become 42=x=y=z.
10082 c) remove conditions that are always false or always true
10083
10084 @param thd Thread handler
10085 @param[in,out] cond WHERE or HAVING condition to optimize
10086 @param[out] cond_equal The built multiple equalities
10087 @param join_list list of join operations with join conditions
10088 = NULL: Called for HAVING condition
10089 @param[out] cond_value Not changed if cond was empty
10090 COND_TRUE if cond is always true
10091 COND_FALSE if cond is impossible
10092 COND_OK otherwise
10093
10094
10095 @returns false if success, true if error
10096 */
10097
10098 1521963 bool optimize_cond(THD *thd, Item **cond, COND_EQUAL **cond_equal,
10099 mem_root_deque<TABLE_LIST *> *join_list,
10100 Item::cond_result *cond_value) {
10101
1/2
✓ Branch 0 taken 1522119 times.
✗ Branch 1 not taken.
1521963 DBUG_TRACE;
10102 1522119 Opt_trace_context *const trace = &thd->opt_trace;
10103
10104
1/2
✓ Branch 0 taken 1522057 times.
✗ Branch 1 not taken.
1522119 Opt_trace_object trace_wrapper(trace);
10105
1/2
✓ Branch 0 taken 1522104 times.
✗ Branch 1 not taken.
1522057 Opt_trace_object trace_cond(trace, "condition_processing");
10106
3/4
✓ Branch 0 taken 1511859 times.
✓ Branch 1 taken 10245 times.
✓ Branch 2 taken 1522071 times.
✗ Branch 3 not taken.
1522104 trace_cond.add_alnum("condition", join_list ? "WHERE" : "HAVING");
10107
1/2
✓ Branch 0 taken 1522103 times.
✗ Branch 1 not taken.
1522071 trace_cond.add("original_condition", *cond);
10108
1/2
✓ Branch 0 taken 1522093 times.
✗ Branch 1 not taken.
1522103 Opt_trace_array trace_steps(trace, "steps");
10109
10110 /*
10111 Enter this function
10112 a) For a WHERE condition or a query having outer join.
10113 b) For a HAVING condition.
10114 */
10115
3/4
✓ Branch 0 taken 5301 times.
✓ Branch 1 taken 1516792 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5301 times.
1522093 assert(*cond || join_list);
10116
10117 /*
10118 Build all multiple equality predicates and eliminate equality
10119 predicates that can be inferred from these multiple equalities.
10120 For each reference of a field included into a multiple equality
10121 that occurs in a function set a pointer to the multiple equality
10122 predicate. Substitute a constant instead of this field if the
10123 multiple equality contains a constant.
10124 This is performed for the WHERE condition and any join conditions, but
10125 not for the HAVING condition.
10126 */
10127
2/2
✓ Branch 0 taken 1511854 times.
✓ Branch 1 taken 10239 times.
1522093 if (join_list) {
10128
1/2
✓ Branch 0 taken 1511863 times.
✗ Branch 1 not taken.
1511854 Opt_trace_object step_wrapper(trace);
10129
1/2
✓ Branch 0 taken 1511863 times.
✗ Branch 1 not taken.
1511863 step_wrapper.add_alnum("transformation", "equality_propagation");
10130 {
10131 Opt_trace_disable_I_S disable_trace_wrapper(
10132
5/6
✓ Branch 0 taken 1506500 times.
✓ Branch 1 taken 5363 times.
✓ Branch 2 taken 1480432 times.
✓ Branch 3 taken 26057 times.
✓ Branch 4 taken 1511763 times.
✗ Branch 5 not taken.
1511863 trace, !(*cond && (*cond)->has_subquery()));
10133
1/2
✓ Branch 0 taken 1511839 times.
✗ Branch 1 not taken.
1511763 Opt_trace_array trace_subselect(trace, "subselect_evaluation");
10134
3/4
✓ Branch 0 taken 1511811 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1511810 times.
1511839 if (build_equal_items(thd, *cond, cond, nullptr, true, join_list,
10135 cond_equal))
10136 1 return true;
10137
2/4
✓ Branch 0 taken 1511759 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1511785 times.
✗ Branch 3 not taken.
1511811 }
10138
1/2
✓ Branch 0 taken 1511791 times.
✗ Branch 1 not taken.
1511785 step_wrapper.add("resulting_condition", *cond);
10139
1/2
✓ Branch 0 taken 1511790 times.
✗ Branch 1 not taken.
1511785 }
10140 /*
10141 change field = field to field = const for each found field = const
10142 Note: Since we disable multi-equalities in the hypergraph optimizer for now,
10143 we also cannot run this optimization; it causes spurious “Impossible WHERE”
10144 in e.g. main.select_none.
10145 */
10146
4/4
✓ Branch 0 taken 1516739 times.
✓ Branch 1 taken 5290 times.
✓ Branch 2 taken 1516680 times.
✓ Branch 3 taken 59 times.
1522029 if (*cond && !thd->lex->using_hypergraph_optimizer) {
10147
1/2
✓ Branch 0 taken 1516705 times.
✗ Branch 1 not taken.
1516680 Opt_trace_object step_wrapper(trace);
10148
1/2
✓ Branch 0 taken 1516713 times.
✗ Branch 1 not taken.
1516705 step_wrapper.add_alnum("transformation", "constant_propagation");
10149 {
10150 Opt_trace_disable_I_S disable_trace_wrapper(trace,
10151
1/2
✓ Branch 0 taken 1516719 times.
✗ Branch 1 not taken.
1516713 !(*cond)->has_subquery());
10152
1/2
✓ Branch 0 taken 1516702 times.
✗ Branch 1 not taken.
1516719 Opt_trace_array trace_subselect(trace, "subselect_evaluation");
10153
3/4
✓ Branch 0 taken 1516615 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1516614 times.
1516702 if (propagate_cond_constants(thd, nullptr, *cond, *cond)) return true;
10154
3/4
✓ Branch 0 taken 1516634 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1516679 times.
✓ Branch 3 taken 26 times.
1516608 }
10155
1/2
✓ Branch 0 taken 1516691 times.
✗ Branch 1 not taken.
1516679 step_wrapper.add("resulting_condition", *cond);
10156
1/2
✓ Branch 0 taken 1516695 times.
✗ Branch 1 not taken.
1516717 }
10157
10158 /*
10159 Remove all instances of item == item
10160 Remove all and-levels where CONST item != CONST item
10161 */
10162
4/6
✓ Branch 0 taken 1522077 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1522062 times.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
1522044 DBUG_EXECUTE("where",
10163 print_where(thd, *cond, "after const change", QT_ORDINARY););
10164
2/2
✓ Branch 0 taken 1516761 times.
✓ Branch 1 taken 5316 times.
1522077 if (*cond) {
10165
1/2
✓ Branch 0 taken 1516769 times.
✗ Branch 1 not taken.
1516761 Opt_trace_object step_wrapper(trace);
10166
1/2
✓ Branch 0 taken 1516771 times.
✗ Branch 1 not taken.
1516769 step_wrapper.add_alnum("transformation", "trivial_condition_removal");
10167 {
10168 Opt_trace_disable_I_S disable_trace_wrapper(trace,
10169
1/2
✓ Branch 0 taken 1516774 times.
✗ Branch 1 not taken.
1516771 !(*cond)->has_subquery());
10170
1/2
✓ Branch 0 taken 1516751 times.
✗ Branch 1 not taken.
1516774 Opt_trace_array trace_subselect(trace, "subselect_evaluation");
10171
3/4
✓ Branch 0 taken 1516678 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 1516644 times.
1516751 if (remove_eq_conds(thd, *cond, cond, cond_value)) return true;
10172
4/4
✓ Branch 0 taken 1516654 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 1516708 times.
✓ Branch 3 taken 42 times.
1516712 }
10173
1/2
✓ Branch 0 taken 1516701 times.
✗ Branch 1 not taken.
1516708 step_wrapper.add("resulting_condition", *cond);
10174
2/2
✓ Branch 0 taken 1516706 times.
✓ Branch 1 taken 29 times.
1516743 }
10175
3/4
✓ Branch 0 taken 1522019 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1522013 times.
1522022 if (thd->is_error()) return true;
10176 1522013 return false;
10177 1522045 }
10178
10179 /**
10180 Checks if a condition can be evaluated during constant folding. It can be
10181 evaluated if it is constant during execution and not expensive to evaluate. If
10182 it contains a subquery, it should not be evaluated if the option
10183 OPTION_NO_SUBQUERY_DURING_OPTIMIZATION is active.
10184 */
10185 14089505 static bool can_evaluate_condition(THD *thd, Item *condition) {
10186
4/4
✓ Branch 0 taken 24575 times.
✓ Branch 1 taken 14064964 times.
✓ Branch 2 taken 24533 times.
✓ Branch 3 taken 42 times.
14114045 return condition->const_for_execution() && !condition->is_expensive() &&
10187
2/2
✓ Branch 0 taken 24523 times.
✓ Branch 1 taken 17 times.
24533 evaluate_during_optimization(condition,
10188 14114079 thd->lex->current_query_block());
10189 }
10190
10191 /**
10192 Calls fold_condition. If that made the condition constant for execution,
10193 simplify and fold again. @see fold_condition() for arguments.
10194 */
10195 7868333 static bool fold_condition_exec(THD *thd, Item *cond, Item **retcond,
10196 Item::cond_result *cond_value) {
10197
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7868368 times.
7868333 if (fold_condition(thd, cond, retcond, cond_value)) return true;
10198
4/4
✓ Branch 0 taken 7862448 times.
✓ Branch 1 taken 5920 times.
✓ Branch 2 taken 124 times.
✓ Branch 3 taken 7868314 times.
15730886 if (*retcond != nullptr &&
10199
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 7862394 times.
7862448 can_evaluate_condition(thd, *retcond)) // simplify further maybe
10200 124 return remove_eq_conds(thd, *retcond, retcond, cond_value);
10201 7868314 return false;
10202 }
10203
10204 /**
10205 Removes const and eq items. Returns the new item, or nullptr if no condition.
10206
10207 @param thd thread handler
10208 @param cond the condition to handle
10209 @param[out] retcond condition after const removal
10210 @param[out] cond_value resulting value of the condition
10211 =COND_OK condition must be evaluated (e.g. field = constant)
10212 =COND_TRUE always true (e.g. 1 = 1)
10213 =COND_FALSE always false (e.g. 1 = 2)
10214
10215 @returns false if success, true if error
10216 */
10217 7921412 bool remove_eq_conds(THD *thd, Item *cond, Item **retcond,
10218 Item::cond_result *cond_value) {
10219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7921604 times.
7921412 assert(cond->real_item()->is_bool_func());
10220
2/2
✓ Branch 0 taken 1694437 times.
✓ Branch 1 taken 6227179 times.
7921604 if (cond->type() == Item::COND_ITEM) {
10221 1694437 Item_cond *const item_cond = down_cast<Item_cond *>(cond);
10222
1/2
✓ Branch 0 taken 1694443 times.
✗ Branch 1 not taken.
1694442 const bool and_level = item_cond->functype() == Item_func::COND_AND_FUNC;
10223
1/2
✓ Branch 0 taken 1694438 times.
✗ Branch 1 not taken.
1694443 List_iterator<Item> li(*item_cond->argument_list());
10224 1694438 bool should_fix_fields = false;
10225 1694438 *cond_value = Item::COND_UNDEF;
10226 Item *item;
10227
2/2
✓ Branch 0 taken 6404240 times.
✓ Branch 1 taken 1688265 times.
8092551 while ((item = li++)) {
10228 Item *new_item;
10229 Item::cond_result tmp_cond_value;
10230
3/4
✓ Branch 0 taken 6404294 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 6404293 times.
6410387 if (remove_eq_conds(thd, item, &new_item, &tmp_cond_value)) return true;
10231
10232
2/2
✓ Branch 0 taken 19034 times.
✓ Branch 1 taken 6385259 times.
6404293 if (new_item == nullptr)
10233
1/2
✓ Branch 0 taken 19001 times.
✗ Branch 1 not taken.
19034 li.remove();
10234
2/2
✓ Branch 0 taken 741 times.
✓ Branch 1 taken 6384518 times.
6385259 else if (item != new_item) {
10235 741 (void)li.replace(new_item);
10236 741 should_fix_fields = true;
10237 }
10238
2/2
✓ Branch 0 taken 1694417 times.
✓ Branch 1 taken 4709843 times.
6404260 if (*cond_value == Item::COND_UNDEF) *cond_value = tmp_cond_value;
10239
3/5
✓ Branch 0 taken 6385246 times.
✓ Branch 1 taken 12863 times.
✓ Branch 2 taken 6171 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6404260 switch (tmp_cond_value) {
10240 6385246 case Item::COND_OK: // Not true or false
10241
4/4
✓ Branch 0 taken 1019970 times.
✓ Branch 1 taken 5365276 times.
✓ Branch 2 taken 269 times.
✓ Branch 3 taken 1019701 times.
6385246 if (and_level || *cond_value == Item::COND_FALSE)
10242 5365545 *cond_value = tmp_cond_value;
10243 6385246 break;
10244 12863 case Item::COND_FALSE:
10245
2/2
✓ Branch 0 taken 5713 times.
✓ Branch 1 taken 7150 times.
12863 if (and_level) // Always false
10246 {
10247 5713 *cond_value = tmp_cond_value;
10248 5713 *retcond = nullptr;
10249 5713 return false;
10250 }
10251 7150 break;
10252 6171 case Item::COND_TRUE:
10253
2/2
✓ Branch 0 taken 434 times.
✓ Branch 1 taken 5737 times.
6171 if (!and_level) // Always true
10254 {
10255 434 *cond_value = tmp_cond_value;
10256 434 *retcond = nullptr;
10257 434 return false;
10258 }
10259 5737 break;
10260 case Item::COND_UNDEF: // Impossible
10261 assert(false); /* purecov: deadcode */
10262 }
10263 }
10264
3/4
✓ Branch 0 taken 520 times.
✓ Branch 1 taken 1687745 times.
✓ Branch 2 taken 520 times.
✗ Branch 3 not taken.
1688265 if (should_fix_fields) item_cond->update_used_tables();
10265
10266
4/4
✓ Branch 0 taken 1688039 times.
✓ Branch 1 taken 250 times.
✓ Branch 2 taken 250 times.
✓ Branch 3 taken 1688039 times.
3376304 if (item_cond->argument_list()->elements == 0 ||
10267
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1688037 times.
1688039 *cond_value != Item::COND_OK) {
10268 250 *retcond = nullptr;
10269 250 return false;
10270 }
10271
2/2
✓ Branch 0 taken 22223 times.
✓ Branch 1 taken 1665815 times.
1688039 if (item_cond->argument_list()->elements == 1) {
10272 /*
10273 BUG#11765699:
10274 We're dealing with an AND or OR item that has only one
10275 argument. However, it is not an option to empty the list
10276 because:
10277
10278 - this function is called for either JOIN::conds or
10279 JOIN::having, but these point to the same condition as
10280 Query_block::where and Query_block::having do.
10281
10282 - The return value of remove_eq_conds() is assigned to
10283 JOIN::conds and JOIN::having, so emptying the list and
10284 returning the only remaining item "replaces" the AND or OR
10285 with item for the variables in JOIN. However, the return
10286 value is not assigned to the Query_block counterparts. Thus,
10287 if argument_list is emptied, Query_block forgets the item in
10288 argument_list()->head().
10289
10290 item is therefore returned, but argument_list is not emptied.
10291 */
10292 22223 item = item_cond->argument_list()->head();
10293 /*
10294 Consider reenabling the line below when the optimizer has been
10295 split into properly separated phases.
10296
10297 item_cond->argument_list()->empty();
10298 */
10299 22221 *retcond = item;
10300 22221 return false;
10301 }
10302
2/2
✓ Branch 0 taken 24399 times.
✓ Branch 1 taken 6202665 times.
6227179 } else if (can_evaluate_condition(thd, cond)) {
10303 bool value;
10304
3/4
✓ Branch 0 taken 24399 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 24368 times.
24399 if (eval_const_cond(thd, cond, &value)) return true;
10305
2/2
✓ Branch 0 taken 6482 times.
✓ Branch 1 taken 17886 times.
24368 *cond_value = value ? Item::COND_TRUE : Item::COND_FALSE;
10306 24368 *retcond = nullptr;
10307 24368 return false;
10308 } else { // Boolean compare function
10309 6202665 *cond_value = cond->eq_cmp_result();
10310
2/2
✓ Branch 0 taken 5030838 times.
✓ Branch 1 taken 1171927 times.
6202765 if (*cond_value == Item::COND_OK) {
10311 5030838 return fold_condition_exec(thd, cond, retcond, cond_value);
10312 }
10313 1171927 Item *left_item = down_cast<Item_func *>(cond)->arguments()[0];
10314 1171950 Item *right_item = down_cast<Item_func *>(cond)->arguments()[1];
10315
6/6
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 1171649 times.
✓ Branch 2 taken 251 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 251 times.
✓ Branch 5 taken 1171650 times.
1171953 if (left_item->eq(right_item, true) && !cond->is_non_deterministic()) {
10316 /*
10317 Two identical items are being compared:
10318 1) If the items are not nullable, return result from eq_cmp_result(),
10319 that is, we can short circuit because result is statically always
10320 known to be true or false, depending on which operator we are
10321 dealing with. If the operator allows equality, *cond_value is
10322 Item::COND_TRUE (a non-null value is always equal to itself), else
10323 Item::COND_FALSE (a non-null value is never unequal to itself).
10324 2) If the items are nullable and the result from eq_cmp_result() is
10325 false, result is always false, that is, the operator doesn't
10326 allow for equality, the result is always false: Any non-null
10327 value cannot obviously be unequal to itself, and any NULL value
10328 would yield an undefined result (e.g. NULL < NULL
10329 is undefined), and hence Item::COND_FALSE in this context is the
10330 effective result.
10331 (Call order ensures test is not applied to conditions with explicit
10332 truth value test)
10333 3) If the <=> operator is used, result is always true because
10334 NULL = NULL is true for this operator
10335 */
10336
6/6
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 37 times.
✓ Branch 4 taken 175 times.
✓ Branch 5 taken 76 times.
337 if (!left_item->is_nullable() || *cond_value == Item::COND_FALSE ||
10337
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 76 times.
86 down_cast<Item_func *>(cond)->functype() == Item_func::EQUAL_FUNC) {
10338 175 *retcond = nullptr;
10339 175 return false;
10340 }
10341 }
10342 }
10343 2837541 return fold_condition_exec(thd, cond, retcond, cond_value);
10344 }
10345
10346 /**
10347 Check if GROUP BY/DISTINCT can be optimized away because the set is
10348 already known to be distinct.
10349
10350 Used in removing the GROUP BY/DISTINCT of the following types of
10351 statements:
10352 @code
10353 SELECT [DISTINCT] <unique_key_cols>... FROM <single_table_ref>
10354 [GROUP BY <unique_key_cols>,...]
10355 @endcode
10356
10357 If (a,b,c is distinct)
10358 then <any combination of a,b,c>,{whatever} is also distinct
10359
10360 This function checks if all the key parts of any of the unique keys
10361 of the table are referenced by a list : either the select list
10362 through find_field_in_item_list or GROUP BY list through
10363 find_field_in_order_list.
10364 If the above holds and the key parts cannot contain NULLs then we
10365 can safely remove the GROUP BY/DISTINCT,
10366 as no result set can be more distinct than an unique key.
10367
10368 @param tab The join table to operate on.
10369 @param find_func function to iterate over the list and search
10370 for a field
10371 @param data data that's passed through to to find_func
10372
10373 @retval
10374 1 found
10375 @retval
10376 0 not found.
10377
10378 @note
10379 The function assumes that make_outerjoin_info() has been called in
10380 order for the check for outer tables to work.
10381 */
10382
10383 5533 static bool list_contains_unique_index(JOIN_TAB *tab,
10384 bool (*find_func)(Field *, void *),
10385 void *data) {
10386 5533 TABLE *table = tab->table();
10387
10388
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 5521 times.
5533 if (tab->is_inner_table_of_outer_join()) return false;
10389
2/2
✓ Branch 0 taken 3536 times.
✓ Branch 1 taken 5057 times.
8593 for (uint keynr = 0; keynr < table->s->keys; keynr++) {
10390
2/2
✓ Branch 0 taken 2322 times.
✓ Branch 1 taken 1214 times.
3536 if (keynr == table->s->primary_key ||
10391
2/2
✓ Branch 0 taken 658 times.
✓ Branch 1 taken 1664 times.
2322 (table->key_info[keynr].flags & HA_NOSAME)) {
10392 1872 KEY *keyinfo = table->key_info + keynr;
10393 KEY_PART_INFO *key_part, *key_part_end;
10394
10395 555 for (key_part = keyinfo->key_part,
10396 1872 key_part_end = key_part + keyinfo->user_defined_key_parts;
10397
2/2
✓ Branch 0 taken 1963 times.
✓ Branch 1 taken 464 times.
2427 key_part < key_part_end; key_part++) {
10398
6/6
✓ Branch 0 taken 1576 times.
✓ Branch 1 taken 387 times.
✓ Branch 2 taken 1021 times.
✓ Branch 3 taken 555 times.
✓ Branch 4 taken 1408 times.
✓ Branch 5 taken 555 times.
1963 if (key_part->field->is_nullable() || !find_func(key_part->field, data))
10399 1408 break;
10400 }
10401
2/2
✓ Branch 0 taken 464 times.
✓ Branch 1 taken 1408 times.
1872 if (key_part == key_part_end) return true;
10402 }
10403 }
10404 5057 return false;
10405 }
10406
10407 /**
10408 Helper function for list_contains_unique_index.
10409 Find a field reference in a list of ORDER structures.
10410 Finds a direct reference of the Field in the list.
10411
10412 @param field The field to search for.
10413 @param data ORDER *.The list to search in
10414
10415 @retval
10416 1 found
10417 @retval
10418 0 not found.
10419 */
10420
10421 644 static bool find_field_in_order_list(Field *field, void *data) {
10422 644 ORDER *group = (ORDER *)data;
10423 644 bool part_found = false;
10424
2/2
✓ Branch 0 taken 699 times.
✓ Branch 1 taken 316 times.
1015 for (ORDER *tmp_group = group; tmp_group; tmp_group = tmp_group->next) {
10425 699 const Item *item = (*tmp_group->item)->real_item();
10426
4/4
✓ Branch 0 taken 588 times.
✓ Branch 1 taken 111 times.
✓ Branch 2 taken 328 times.
✓ Branch 3 taken 371 times.
1287 if (item->type() == Item::FIELD_ITEM &&
10427
2/2
✓ Branch 0 taken 328 times.
✓ Branch 1 taken 260 times.
588 down_cast<const Item_field *>(item)->field->eq(field)) {
10428 328 part_found = true;
10429 328 break;
10430 }
10431 }
10432 644 return part_found;
10433 }
10434
10435 /**
10436 Helper function for list_contains_unique_index.
10437 Find a field reference in a dynamic list of Items.
10438 Finds a direct reference of the Field in the list.
10439
10440 @param[in] field The field to search for.
10441 @param[in] data List<Item> *.The list to search in
10442
10443 @retval
10444 1 found
10445 @retval
10446 0 not found.
10447 */
10448
10449 932 static bool find_field_in_item_list(Field *field, void *data) {
10450 932 mem_root_deque<Item *> *fields =
10451 reinterpret_cast<mem_root_deque<Item *> *>(data);
10452 932 bool part_found = false;
10453
10454
8/14
✓ Branch 0 taken 932 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 932 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 932 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1023 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 796 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1728 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1023 times.
✓ Branch 13 taken 705 times.
1728 for (const Item *item : VisibleFields(*fields)) {
10455
5/6
✓ Branch 0 taken 1023 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 784 times.
✓ Branch 3 taken 239 times.
✓ Branch 4 taken 227 times.
✓ Branch 5 taken 796 times.
1807 if (item->type() == Item::FIELD_ITEM &&
10456
3/4
✓ Branch 0 taken 784 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 227 times.
✓ Branch 3 taken 557 times.
784 down_cast<const Item_field *>(item)->field->eq(field)) {
10457 227 part_found = true;
10458 227 break;
10459 }
10460 }
10461 932 return part_found;
10462 }
10463
10464 3090 ORDER *create_order_from_distinct(THD *thd, Ref_item_array ref_item_array,
10465 ORDER *order_list,
10466 mem_root_deque<Item *> *fields,
10467 bool skip_aggregates,
10468 bool convert_bit_fields_to_long,
10469 bool *all_order_by_fields_used) {
10470 3090 ORDER *group = nullptr, **prev = &group;
10471
10472 3090 *all_order_by_fields_used = true;
10473
10474
2/2
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 3090 times.
3399 for (ORDER *order = order_list; order; order = order->next) {
10475
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 72 times.
309 if (order->in_field_list) {
10476
1/2
✓ Branch 0 taken 237 times.
✗ Branch 1 not taken.
237 ORDER *ord = (ORDER *)thd->memdup((char *)order, sizeof(ORDER));
10477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 237 times.
237 if (!ord) return nullptr;
10478 237 *prev = ord;
10479 237 prev = &ord->next;
10480 237 (*ord->item)->marker = Item::MARKER_DISTINCT_GROUP;
10481 } else
10482 72 *all_order_by_fields_used = false;
10483 }
10484
10485
1/2
✓ Branch 0 taken 3090 times.
✗ Branch 1 not taken.
3090 Mem_root_array<std::pair<Item *, ORDER *>> bit_fields_to_add(thd->mem_root);
10486
10487
8/14
✓ Branch 0 taken 3090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3090 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3090 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4421 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4421 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 7511 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4421 times.
✓ Branch 13 taken 3090 times.
7511 for (Item *&item : VisibleFields(*fields)) {
10488
8/10
✓ Branch 0 taken 4421 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4302 times.
✓ Branch 3 taken 119 times.
✓ Branch 4 taken 4169 times.
✓ Branch 5 taken 133 times.
✓ Branch 6 taken 4169 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 356 times.
✓ Branch 9 taken 4065 times.
8723 if (!item->const_item() && (!skip_aggregates || !item->has_aggregation()) &&
10489
2/2
✓ Branch 0 taken 4065 times.
✓ Branch 1 taken 237 times.
4302 item->marker != Item::MARKER_DISTINCT_GROUP) {
10490 /*
10491 Don't put duplicate columns from the SELECT list into the
10492 GROUP BY list.
10493 */
10494 ORDER *ord_iter;
10495
2/2
✓ Branch 0 taken 3007 times.
✓ Branch 1 taken 4054 times.
7061 for (ord_iter = group; ord_iter; ord_iter = ord_iter->next)
10496
3/4
✓ Branch 0 taken 3007 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 2996 times.
3007 if ((*ord_iter->item)->eq(item, true)) goto next_item;
10497
10498
1/2
✓ Branch 0 taken 4054 times.
✗ Branch 1 not taken.
4054 ORDER *ord = (ORDER *)thd->mem_calloc(sizeof(ORDER));
10499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4054 times.
4054 if (!ord) return nullptr;
10500
10501
3/4
✓ Branch 0 taken 4054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3456 times.
7516 if (item->type() == Item::FIELD_ITEM &&
10502
6/6
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 592 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 4049 times.
7516 item->data_type() == MYSQL_TYPE_BIT && convert_bit_fields_to_long) {
10503 /*
10504 Because HEAP tables can't index BIT fields we need to use an
10505 additional hidden field for grouping because later it will be
10506 converted to a LONG field. Original field will remain of the
10507 BIT type and will be returned to a client.
10508 @note setup_ref_array() needs to account for the extra space.
10509 @note We need to defer the actual adding to after the loop,
10510 or we will invalidate the iterator to “fields”.
10511 */
10512
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 Item_field *new_item = new Item_field(thd, (Item_field *)item);
10513 5 ord->item = &item; // Temporary; for the duplicate check above.
10514
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 bit_fields_to_add.push_back(std::make_pair(new_item, ord));
10515
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 4027 times.
4049 } else if (ref_item_array.is_null()) {
10516 // No slices are in use, so just use the field from the list.
10517 22 ord->item = &item;
10518 } else {
10519 /*
10520 We have here only visible fields, so we can use simple indexing
10521 of ref_item_array (order in the array and in the list are same)
10522 */
10523 4027 ord->item = &ref_item_array[0];
10524 }
10525 4054 ord->direction = ORDER_ASC;
10526 4054 *prev = ord;
10527 4054 prev = &ord->next;
10528 }
10529 356 next_item:
10530
2/2
✓ Branch 0 taken 4399 times.
✓ Branch 1 taken 22 times.
4421 if (!ref_item_array.is_null()) {
10531 4399 ref_item_array.pop_front();
10532 }
10533 }
10534
3/4
✓ Branch 0 taken 3090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 3090 times.
3095 for (const auto &item_and_order : bit_fields_to_add) {
10535 10 item_and_order.second->item =
10536
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 thd->lex->current_query_block()->add_hidden_item(item_and_order.first);
10537 5 thd->lex->current_query_block()->hidden_items_from_optimization++;
10538 }
10539 3090 *prev = nullptr;
10540 3090 return group;
10541 3090 }
10542
10543 /**
10544 Return table number if there is only one table in sort order
10545 and group and order is compatible, else return 0.
10546 */
10547
10548 1867020 static TABLE *get_sort_by_table(ORDER *a, ORDER *b, TABLE_LIST *tables) {
10549
1/2
✓ Branch 0 taken 1867080 times.
✗ Branch 1 not taken.
1867020 DBUG_TRACE;
10550 1867080 table_map map = (table_map)0;
10551
10552
2/2
✓ Branch 0 taken 1315637 times.
✓ Branch 1 taken 551443 times.
1867080 if (!a)
10553 1315637 a = b; // Only one need to be given
10554
2/2
✓ Branch 0 taken 547876 times.
✓ Branch 1 taken 3567 times.
551443 else if (!b)
10555 547876 b = a;
10556
10557
4/4
✓ Branch 0 taken 901169 times.
✓ Branch 1 taken 1866251 times.
✓ Branch 2 taken 901135 times.
✓ Branch 3 taken 34 times.
2767420 for (; a && b; a = a->next, b = b->next) {
10558
3/4
✓ Branch 0 taken 901135 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 795 times.
✓ Branch 3 taken 900340 times.
901135 if (!(*a->item)->eq(*b->item, true)) return nullptr;
10559
1/2
✓ Branch 0 taken 900340 times.
✗ Branch 1 not taken.
900340 map |= a->item[0]->used_tables();
10560 }
10561 1866285 map &= ~INNER_TABLE_BIT;
10562
4/4
✓ Branch 0 taken 570417 times.
✓ Branch 1 taken 1295868 times.
✓ Branch 2 taken 347 times.
✓ Branch 3 taken 570070 times.
1866285 if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))) return nullptr;
10563
10564
2/2
✓ Branch 0 taken 26581 times.
✓ Branch 1 taken 570070 times.
596651 for (; !(map & tables->map()); tables = tables->next_leaf)
10565 ;
10566
2/2
✓ Branch 0 taken 135074 times.
✓ Branch 1 taken 434996 times.
570070 if (map != tables->map()) return nullptr; // More than one table
10567
5/8
✓ Branch 0 taken 434996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 434996 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 434995 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
434996 DBUG_PRINT("exit", ("sort by table: %d", tables->tableno()));
10568 434996 return tables->table;
10569 1867080 }
10570
10571 /**
10572 Update some values in keyuse for faster choose_table_order() loop.
10573
10574 @todo Check if this is the real meaning of ref_table_rows.
10575 */
10576
10577 1767443 void JOIN::optimize_keyuse() {
10578
2/2
✓ Branch 0 taken 4649266 times.
✓ Branch 1 taken 1767491 times.
6416747 for (size_t ix = 0; ix < keyuse_array.size(); ++ix) {
10579 4649266 Key_use *keyuse = &keyuse_array.at(ix);
10580 table_map map;
10581 /*
10582 If we find a ref, assume this table matches a proportional
10583 part of this table.
10584 For example 100 records matching a table with 5000 records
10585 gives 5000/100 = 50 records per key
10586 Constant tables are ignored.
10587 To avoid bad matches, we don't make ref_table_rows less than 100.
10588 */
10589 4649354 keyuse->ref_table_rows = ~(ha_rows)0; // If no ref
10590 4649354 if (keyuse->used_tables &
10591
2/2
✓ Branch 0 taken 4068061 times.
✓ Branch 1 taken 581293 times.
4649354 (map = keyuse->used_tables & ~(const_table_map | PSEUDO_TABLE_BITS))) {
10592 uint tableno;
10593
2/2
✓ Branch 0 taken 15156384 times.
✓ Branch 1 taken 4068061 times.
19224445 for (tableno = 0; !(map & 1); map >>= 1, tableno++) {
10594 }
10595
2/2
✓ Branch 0 taken 4067280 times.
✓ Branch 1 taken 781 times.
4068061 if (map == 1) // Only one table
10596 {
10597 4067280 TABLE *tmp_table = join_tab[tableno].table();
10598
10599 4067230 keyuse->ref_table_rows =
10600 4067284 max<ha_rows>(tmp_table->file->stats.records, 100);
10601 }
10602 }
10603 /*
10604 Outer reference (external field) is constant for single executing
10605 of subquery
10606 */
10607
2/2
✓ Branch 0 taken 5379 times.
✓ Branch 1 taken 4643925 times.
4649304 if (keyuse->used_tables == OUTER_REF_TABLE_BIT) keyuse->ref_table_rows = 1;
10608 }
10609 1767491 }
10610
10611 /**
10612 Function sets FT hints, initializes FT handlers
10613 and checks if FT index can be used as covered.
10614 */
10615
10616 2335 bool JOIN::optimize_fts_query() {
10617
3/6
✓ Branch 0 taken 2335 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2335 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2335 times.
✗ Branch 5 not taken.
2335 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
10618
10619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2335 times.
2335 assert(query_block->has_ft_funcs());
10620
10621 // Only used by the old optimizer.
10622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2335 times.
2335 assert(!thd->lex->using_hypergraph_optimizer);
10623
10624
2/2
✓ Branch 0 taken 4946 times.
✓ Branch 1 taken 2335 times.
7281 for (uint i = const_tables; i < tables; i++) {
10625 4946 JOIN_TAB *tab = best_ref[i];
10626
2/2
✓ Branch 0 taken 2776 times.
✓ Branch 1 taken 2170 times.
4946 if (tab->type() != JT_FT) continue;
10627
10628 Item_func_match *ifm;
10629 Item_func_match *ft_func =
10630 2170 down_cast<Item_func_match *>(tab->position()->key->val);
10631
1/2
✓ Branch 0 taken 2170 times.
✗ Branch 1 not taken.
2170 List_iterator<Item_func_match> li(*(query_block->ftfunc_list));
10632
10633
2/2
✓ Branch 0 taken 2306 times.
✓ Branch 1 taken 2170 times.
4476 while ((ifm = li++)) {
10634
6/6
✓ Branch 0 taken 2271 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 75 times.
✓ Branch 3 taken 2196 times.
✓ Branch 4 taken 110 times.
✓ Branch 5 taken 2196 times.
2306 if (!(ifm->used_tables() & tab->table_ref->map()) || ifm->master)
10635 110 continue;
10636
10637
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 2170 times.
2196 if (ifm != ft_func) {
10638
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 20 times.
26 if (ifm->can_skip_ranking())
10639
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 ifm->set_hints(this, FT_NO_RANKING, HA_POS_ERROR, false);
10640 }
10641 }
10642
10643 /*
10644 Check if internal sorting is needed. FT_SORTED flag is set
10645 if no ORDER BY clause or ORDER BY MATCH function is the same
10646 as the function that is used for FT index and FT table is
10647 the first non-constant table in the JOIN.
10648 */
10649
8/8
✓ Branch 0 taken 2145 times.
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 978 times.
✓ Branch 3 taken 1167 times.
✓ Branch 4 taken 64 times.
✓ Branch 5 taken 914 times.
✓ Branch 6 taken 931 times.
✓ Branch 7 taken 1239 times.
3212 if (i == const_tables && !(ft_func->get_hints()->get_flags() & FT_BOOL) &&
10650
3/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 47 times.
1042 (order.empty() || ft_func == test_if_ft_index_order(order.order)))
10651
1/2
✓ Branch 0 taken 931 times.
✗ Branch 1 not taken.
931 ft_func->set_hints(this, FT_SORTED, m_select_limit, false);
10652
10653 /*
10654 Check if ranking is not needed. FT_NO_RANKING flag is set if
10655 MATCH function is used only in WHERE condition and MATCH
10656 function is not part of an expression.
10657 */
10658
2/2
✓ Branch 0 taken 1279 times.
✓ Branch 1 taken 891 times.
2170 if (ft_func->can_skip_ranking())
10659
3/4
✓ Branch 0 taken 1233 times.
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 1279 times.
✗ Branch 3 not taken.
1279 ft_func->set_hints(this, FT_NO_RANKING,
10660 1279 order.empty() ? m_select_limit : HA_POS_ERROR, false);
10661 }
10662
10663 2335 return init_ftfuncs(thd, query_block);
10664 }
10665
10666 /**
10667 Check if FTS index only access is possible.
10668
10669 @param tab pointer to JOIN_TAB structure.
10670
10671 @return true if index only access is possible,
10672 false otherwise.
10673 */
10674
10675 2177 bool JOIN::fts_index_access(JOIN_TAB *tab) {
10676
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2177 times.
2177 assert(tab->type() == JT_FT);
10677 2177 TABLE *table = tab->table();
10678
10679 // Give up if index-only access has already been disabled on this table.
10680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2177 times.
2177 if (table->no_keyread) {
10681 return false;
10682 }
10683
10684
2/2
✓ Branch 0 taken 239 times.
✓ Branch 1 taken 1938 times.
2177 if ((table->file->ha_table_flags() & HA_CAN_FULLTEXT_EXT) == 0)
10685 239 return false; // Optimizations requires extended FTS support by table
10686 // engine
10687
10688 /*
10689 This optimization does not work with filesort nor GROUP BY
10690 */
10691
4/4
✓ Branch 0 taken 1932 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 1872 times.
3870 if (grouped ||
10692
4/4
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 1842 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 30 times.
1932 (!order.empty() && m_ordered_index_usage != ORDERED_INDEX_ORDER_BY))
10693 66 return false;
10694
10695 /*
10696 Check whether the FTS result is covering. If only document id
10697 and rank is needed, there is no need to access table rows.
10698 */
10699
2/2
✓ Branch 0 taken 1946 times.
✓ Branch 1 taken 57 times.
2003 for (uint i = bitmap_get_first_set(table->read_set); i < table->s->fields;
10700 131 i = bitmap_get_next_set(table->read_set, i)) {
10701
4/4
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 1815 times.
✓ Branch 2 taken 1815 times.
✓ Branch 3 taken 131 times.
2077 if (table->field[i] != table->fts_doc_id_field ||
10702
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131 times.
131 !tab->ft_func()->docid_in_result())
10703 1815 return false;
10704 }
10705
10706 57 return true;
10707 }
10708
10709 /**
10710 For {semijoin,subquery} materialization: calculates various cost
10711 information, based on a plan in join->best_positions covering the
10712 to-be-materialized query block and only this.
10713
10714 @param join JOIN where plan can be found
10715 @param sj_nest sj materialization nest (NULL if subquery materialization)
10716 @param n_tables number of to-be-materialized tables
10717 @param[out] sjm where computed costs will be stored
10718
10719 @note that this function modifies join->map2table, which has to be filled
10720 correctly later.
10721 */
10722 11033 static void calculate_materialization_costs(JOIN *join, TABLE_LIST *sj_nest,
10723 uint n_tables,
10724 Semijoin_mat_optimize *sjm) {
10725 double mat_cost; // Estimated cost of materialization
10726 double mat_rowcount; // Estimated row count before duplicate removal
10727 double distinct_rowcount; // Estimated rowcount after duplicate removal
10728 mem_root_deque<Item *> *inner_expr_list;
10729
10730
2/2
✓ Branch 0 taken 8684 times.
✓ Branch 1 taken 2349 times.
11033 if (sj_nest) {
10731 /*
10732 get_partial_join_cost() assumes a regular join, which is correct when
10733 we optimize a sj-materialization nest (always executed as regular
10734 join).
10735 */
10736
1/2
✓ Branch 0 taken 8684 times.
✗ Branch 1 not taken.
8684 get_partial_join_cost(join, n_tables, &mat_cost, &mat_rowcount);
10737 8684 n_tables += join->const_tables;
10738 8684 inner_expr_list = &sj_nest->nested_join->sj_inner_exprs;
10739 } else {
10740 2349 mat_cost = join->best_read;
10741 2349 mat_rowcount = static_cast<double>(join->best_rowcount);
10742 2349 inner_expr_list = &join->query_block->fields;
10743 }
10744
10745 /*
10746 Adjust output cardinality estimates. If the subquery has form
10747
10748 ... oe IN (SELECT t1.colX, t2.colY, func(X,Y,Z) )
10749
10750 then the number of distinct output record combinations has an
10751 upper bound of product of number of records matching the tables
10752 that are used by the SELECT clause.
10753 TODO:
10754 We can get a more precise estimate if we
10755 - use rec_per_key cardinality estimates. For simple cases like
10756 "oe IN (SELECT t.key ...)" it is trivial.
10757 - Functional dependencies between the tables in the semi-join
10758 nest (the payoff is probably less here?)
10759 */
10760 {
10761
2/2
✓ Branch 0 taken 21813 times.
✓ Branch 1 taken 11033 times.
32846 for (uint i = 0; i < n_tables; i++) {
10762 21813 JOIN_TAB *const tab = join->best_positions[i].table;
10763 21813 join->map2table[tab->table_ref->tableno()] = tab;
10764 }
10765 11033 table_map map = 0;
10766
7/12
✓ Branch 0 taken 11033 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11033 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11033 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12040 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 23073 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 12040 times.
✓ Branch 11 taken 11033 times.
23073 for (Item *item : VisibleFields(*inner_expr_list)) {
10767
2/4
✓ Branch 0 taken 12040 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12040 times.
✗ Branch 3 not taken.
12040 map |= item->used_tables();
10768 }
10769 11033 map &= ~PSEUDO_TABLE_BITS;
10770 11033 Table_map_iterator tm_it(map);
10771 int tableno;
10772 11033 double rows = 1.0;
10773
2/2
✓ Branch 0 taken 11354 times.
✓ Branch 1 taken 11033 times.
22387 while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
10774 11354 rows *= join->map2table[tableno]->table()->quick_condition_rows;
10775 11033 distinct_rowcount = min(mat_rowcount, rows);
10776 }
10777 /*
10778 Calculate temporary table parameters and usage costs
10779 */
10780
1/2
✓ Branch 0 taken 11033 times.
✗ Branch 1 not taken.
11033 const uint rowlen = get_tmp_table_rec_length(*inner_expr_list);
10781
10782
1/2
✓ Branch 0 taken 11033 times.
✗ Branch 1 not taken.
11033 const Cost_model_server *cost_model = join->cost_model();
10783
10784 Cost_model_server::enum_tmptable_type tmp_table_type;
10785
2/2
✓ Branch 0 taken 10995 times.
✓ Branch 1 taken 38 times.
11033 if (rowlen * distinct_rowcount < join->thd->variables.max_heap_table_size)
10786 10995 tmp_table_type = Cost_model_server::MEMORY_TMPTABLE;
10787 else
10788 38 tmp_table_type = Cost_model_server::DISK_TMPTABLE;
10789
10790 /*
10791 Let materialization cost include the cost to create the temporary
10792 table and write the rows into it:
10793 */
10794 11033 mat_cost += cost_model->tmptable_create_cost(tmp_table_type);
10795 11033 mat_cost +=
10796 11033 cost_model->tmptable_readwrite_cost(tmp_table_type, mat_rowcount, 0.0);
10797
10798 11033 sjm->materialization_cost.reset();
10799 11033 sjm->materialization_cost.add_io(mat_cost);
10800
10801 11033 sjm->expected_rowcount = distinct_rowcount;
10802
10803 /*
10804 Set the cost to do a full scan of the temptable (will need this to
10805 consider doing sjm-scan):
10806 */
10807 11033 sjm->scan_cost.reset();
10808
2/2
✓ Branch 0 taken 11012 times.
✓ Branch 1 taken 21 times.
11033 if (distinct_rowcount > 0.0) {
10809 11012 const double scan_cost = cost_model->tmptable_readwrite_cost(
10810 tmp_table_type, 0.0, distinct_rowcount);
10811 11012 sjm->scan_cost.add_io(scan_cost);
10812 }
10813
10814 // The cost to lookup a row in temp. table
10815 const double row_cost =
10816 11033 cost_model->tmptable_readwrite_cost(tmp_table_type, 0.0, 1.0);
10817 11033 sjm->lookup_cost.reset();
10818 11033 sjm->lookup_cost.add_io(row_cost);
10819 11033 }
10820
10821 /**
10822 Decides between EXISTS and materialization; performs last steps to set up
10823 the chosen strategy.
10824 @returns 'false' if no error
10825
10826 @note If UNION this is called on each contained JOIN.
10827
10828 */
10829 106041 bool JOIN::decide_subquery_strategy() {
10830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106041 times.
106041 assert(query_expression()->item);
10831
10832
3/4
✓ Branch 0 taken 106041 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12569 times.
✓ Branch 3 taken 93472 times.
106041 switch (query_expression()->item->substype()) {
10833 12569 case Item_subselect::IN_SUBS:
10834 case Item_subselect::ALL_SUBS:
10835 case Item_subselect::ANY_SUBS:
10836 // All of those are children of Item_in_subselect and may use EXISTS
10837 12569 break;
10838 93472 default:
10839 93472 return false;
10840 }
10841
10842 Item_in_subselect *const in_pred =
10843 12569 static_cast<Item_in_subselect *>(query_expression()->item);
10844
10845 12569 Subquery_strategy chosen_method = in_pred->strategy;
10846 // Materialization does not allow UNION so this can't happen:
10847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12569 times.
12569 assert(chosen_method != Subquery_strategy::SUBQ_MATERIALIZATION);
10848
10849
3/4
✓ Branch 0 taken 12261 times.
✓ Branch 1 taken 308 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12569 times.
24830 if ((chosen_method == Subquery_strategy::CANDIDATE_FOR_IN2EXISTS_OR_MAT) &&
10850
2/4
✓ Branch 0 taken 12261 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12261 times.
12261 compare_costs_of_subquery_strategies(&chosen_method))
10851 return true;
10852
10853
2/3
✓ Branch 0 taken 10458 times.
✓ Branch 1 taken 2111 times.
✗ Branch 2 not taken.
12569 switch (chosen_method) {
10854 10458 case Subquery_strategy::SUBQ_EXISTS:
10855
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 10450 times.
10458 if (query_block->m_windows.elements > 0) // grep for WL#10431
10856 {
10857
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
10858 "the combination of this ALL/ANY/SOME/IN subquery with this"
10859 " comparison operator and with contained window functions");
10860 8 return true;
10861 }
10862
1/2
✓ Branch 0 taken 10450 times.
✗ Branch 1 not taken.
10450 return in_pred->finalize_exists_transform(thd, query_block);
10863 2111 case Subquery_strategy::SUBQ_MATERIALIZATION:
10864
1/2
✓ Branch 0 taken 2111 times.
✗ Branch 1 not taken.
2111 return in_pred->finalize_materialization_transform(thd, this);
10865 default:
10866 assert(false);
10867 return true;
10868 }
10869 }
10870
10871 /**
10872 Tells what is the cheapest between IN->EXISTS and subquery materialization,
10873 in terms of cost, for the subquery's JOIN.
10874 Input:
10875 - join->{best_positions,best_read,best_rowcount} must contain the
10876 execution plan of EXISTS (where 'join' is the subquery's JOIN)
10877 - join2->{best_positions,best_read,best_rowcount} must be correctly set
10878 (where 'join2' is the parent join, the grandparent join, etc).
10879 Output:
10880 join->{best_positions,best_read,best_rowcount} contain the cheapest
10881 execution plan (where 'join' is the subquery's JOIN).
10882
10883 This plan choice has to happen before calling functions which set up
10884 execution structures, like JOIN::get_best_combination().
10885
10886 @param[out] method chosen method (EXISTS or materialization) will be put
10887 here.
10888 @returns false if success
10889 */
10890 12261 bool JOIN::compare_costs_of_subquery_strategies(Subquery_strategy *method) {
10891 12261 *method = Subquery_strategy::SUBQ_EXISTS;
10892
10893
1/2
✓ Branch 0 taken 12261 times.
✗ Branch 1 not taken.
12261 Subquery_strategy allowed_strategies = query_block->subquery_strategy(thd);
10894
10895 /*
10896 A non-deterministic subquery should not use materialization, unless forced.
10897 For a detailed explanation, see Query_block::decorrelate_where_cond().
10898 Here, the same logic is applied also for subqueries that are not converted
10899 to semi-join.
10900 */
10901
4/4
✓ Branch 0 taken 1087 times.
✓ Branch 1 taken 11174 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 12255 times.
13348 if (allowed_strategies == Subquery_strategy::CANDIDATE_FOR_IN2EXISTS_OR_MAT &&
10902
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1081 times.
1087 (query_expression()->uncacheable & UNCACHEABLE_RAND))
10903 6 allowed_strategies = Subquery_strategy::SUBQ_EXISTS;
10904
10905
2/2
✓ Branch 0 taken 7354 times.
✓ Branch 1 taken 4907 times.
12261 if (allowed_strategies == Subquery_strategy::SUBQ_EXISTS) return false;
10906
10907
3/4
✓ Branch 0 taken 3826 times.
✓ Branch 1 taken 1081 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3826 times.
4907 assert(allowed_strategies ==
10908 Subquery_strategy::CANDIDATE_FOR_IN2EXISTS_OR_MAT ||
10909 allowed_strategies == Subquery_strategy::SUBQ_MATERIALIZATION);
10910
10911 4907 const JOIN *parent_join = query_expression()->outer_query_block()->join;
10912
4/4
✓ Branch 0 taken 4872 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 762 times.
✓ Branch 3 taken 4110 times.
4907 if (!parent_join || !parent_join->child_subquery_can_materialize)
10913 797 return false;
10914
10915 Item_in_subselect *const in_pred =
10916 4110 static_cast<Item_in_subselect *>(query_expression()->item);
10917
10918 /*
10919 Testing subquery_allows_etc() at each optimization is necessary as each
10920 execution of a prepared statement may use a different type of parameter.
10921 */
10922
2/2
✓ Branch 0 taken 1761 times.
✓ Branch 1 taken 2349 times.
4110 if (!in_pred->subquery_allows_materialization(
10923
1/2
✓ Branch 0 taken 4110 times.
✗ Branch 1 not taken.
4110 thd, query_block, query_block->outer_query_block()))
10924 1761 return false;
10925
10926 2349 Opt_trace_context *const trace = &thd->opt_trace;
10927
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 Opt_trace_object trace_wrapper(trace);
10928 Opt_trace_object trace_subqmat(
10929
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 trace, "execution_plan_for_potential_materialization");
10930 2349 const double saved_best_read = best_read;
10931 2349 const ha_rows saved_best_rowcount = best_rowcount;
10932 2349 POSITION *const saved_best_pos = best_positions;
10933
10934
2/2
✓ Branch 0 taken 2069 times.
✓ Branch 1 taken 280 times.
2349 if (in_pred->in2exists_added_to_where()) {
10935
1/2
✓ Branch 0 taken 2069 times.
✗ Branch 1 not taken.
2069 Opt_trace_array trace_subqmat_steps(trace, "steps");
10936
10937 // Up to one extra slot per semi-join nest is needed (if materialized)
10938 2069 const uint sj_nests = query_block->sj_nests.size();
10939
10940
2/4
✓ Branch 0 taken 2069 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2069 times.
2069 if (!(best_positions = new (thd->mem_root) POSITION[tables + sj_nests]))
10941 return true;
10942
10943 // Compute plans which do not use outer references
10944
10945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2069 times.
2069 assert(allow_outer_refs);
10946 2069 allow_outer_refs = false;
10947
10948
2/4
✓ Branch 0 taken 2069 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2069 times.
2069 if (optimize_semijoin_nests_for_materialization(this)) return true;
10949
10950
3/6
✓ Branch 0 taken 2069 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2069 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2069 times.
2069 if (Optimize_table_order(thd, this, nullptr).choose_table_order())
10951 return true;
10952
1/2
✓ Branch 0 taken 2069 times.
✗ Branch 1 not taken.
2069 } else {
10953 /*
10954 If IN->EXISTS didn't add any condition to WHERE (only to HAVING, which
10955 can happen if subquery has aggregates) then the plan for materialization
10956 will be the same as for EXISTS - don't compute it again.
10957 */
10958
1/2
✓ Branch 0 taken 280 times.
✗ Branch 1 not taken.
280 trace_subqmat.add("surely_same_plan_as_EXISTS", true)
10959
1/2
✓ Branch 0 taken 280 times.
✗ Branch 1 not taken.
280 .add_alnum("cause", "EXISTS_did_not_change_WHERE");
10960 }
10961
10962 2349 Semijoin_mat_optimize sjm;
10963
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 calculate_materialization_costs(this, nullptr, primary_tables, &sjm);
10964
10965 /*
10966 The number of evaluations of the subquery influences costs, we need to
10967 compute it.
10968 */
10969
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 Opt_trace_object trace_subq_mat_decision(trace, "subq_mat_decision");
10970
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 const double subq_executions = calculate_subquery_executions(in_pred, trace);
10971 2349 const double cost_exists = subq_executions * saved_best_read;
10972 2349 const double cost_mat_table = sjm.materialization_cost.total_cost();
10973 const double cost_mat =
10974 2349 cost_mat_table + subq_executions * sjm.lookup_cost.total_cost();
10975 2349 const bool mat_chosen =
10976 (allowed_strategies == Subquery_strategy::CANDIDATE_FOR_IN2EXISTS_OR_MAT)
10977
4/4
✓ Branch 0 taken 416 times.
✓ Branch 1 taken 1933 times.
✓ Branch 2 taken 178 times.
✓ Branch 3 taken 238 times.
2349 ? (cost_mat < cost_exists)
10978 : true;
10979 trace_subq_mat_decision
10980
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 .add("cost_to_create_and_fill_materialized_table", cost_mat_table)
10981
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 .add("cost_of_one_EXISTS", saved_best_read)
10982
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 .add("number_of_subquery_evaluations", subq_executions)
10983
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 .add("cost_of_materialization", cost_mat)
10984
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 .add("cost_of_EXISTS", cost_exists)
10985
1/2
✓ Branch 0 taken 2349 times.
✗ Branch 1 not taken.
2349 .add("chosen", mat_chosen);
10986
2/2
✓ Branch 0 taken 2111 times.
✓ Branch 1 taken 238 times.
2349 if (mat_chosen) {
10987 2111 *method = Subquery_strategy::SUBQ_MATERIALIZATION;
10988 } else {
10989 238 best_read = saved_best_read;
10990 238 best_rowcount = saved_best_rowcount;
10991 238 best_positions = saved_best_pos;
10992 /*
10993 Don't restore JOIN::positions or best_ref, they're not used
10994 afterwards. best_positions is (like: by get_sj_strategy()).
10995 */
10996 }
10997 2349 return false;
10998 2349 }
10999
11000 15625 double calculate_subquery_executions(const Item_subselect *subquery,
11001 Opt_trace_context *trace) {
11002
1/2
✓ Branch 0 taken 15625 times.
✗ Branch 1 not taken.
15625 Opt_trace_array trace_parents(trace, "parent_fanouts");
11003 15625 double subquery_executions = 1.0;
11004 for (;;) {
11005 const Query_block *const parent_query_block =
11006 19971 subquery->unit->outer_query_block();
11007 19971 const JOIN *const parent_join = parent_query_block->join;
11008
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19971 times.
19971 if (parent_join == nullptr) {
11009 /*
11010 May be single-table UPDATE/DELETE, has no join.
11011 @todo we should find how many rows it plans to UPDATE/DELETE, taking
11012 inspiration in Explain_table::explain_rows_and_filtered().
11013 This is not a priority as it applies only to
11014 UPDATE - child(non-mat-subq) - grandchild(may-be-mat-subq).
11015 And it will autosolve the day UPDATE gets a JOIN.
11016 */
11017 break;
11018 }
11019
11020
1/2
✓ Branch 0 taken 19971 times.
✗ Branch 1 not taken.
19971 Opt_trace_object trace_parent(trace);
11021
1/2
✓ Branch 0 taken 19971 times.
✗ Branch 1 not taken.
19971 trace_parent.add_select_number(parent_query_block->select_number);
11022 double parent_fanout;
11023 19971 if ( // safety, not sure needed
11024
4/4
✓ Branch 0 taken 15639 times.
✓ Branch 1 taken 4332 times.
✓ Branch 2 taken 4332 times.
✓ Branch 3 taken 15639 times.
35610 parent_join->plan_is_const() ||
11025 // if subq is in condition on constant table:
11026
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15639 times.
15639 !parent_join->child_subquery_can_materialize) {
11027 4332 parent_fanout = 1.0;
11028
1/2
✓ Branch 0 taken 4332 times.
✗ Branch 1 not taken.
4332 trace_parent.add("subq_attached_to_const_table", true);
11029 } else {
11030
2/2
✓ Branch 0 taken 10405 times.
✓ Branch 1 taken 5234 times.
15639 if (subquery->in_cond_of_tab != NO_PLAN_IDX) {
11031 /*
11032 Subquery is attached to a certain 'pos', pos[-1].prefix_rowcount
11033 is the number of times we'll start a loop accessing 'pos'; each such
11034 loop will read pos->rows_fetched rows of 'pos', so subquery will
11035 be evaluated pos[-1].prefix_rowcount * pos->rows_fetched times.
11036 Exceptions:
11037 - if 'pos' is first, use 1.0 instead of pos[-1].prefix_rowcount
11038 - if 'pos' is first of a sj-materialization nest, same.
11039
11040 If in a sj-materialization nest, pos->rows_fetched and
11041 pos[-1].prefix_rowcount are of the "nest materialization" plan
11042 (copied back in fix_semijoin_strategies()), which is
11043 appropriate as it corresponds to evaluations of our subquery.
11044
11045 pos->prefix_rowcount is not suitable because if we have:
11046 select ... from ot1 where ot1.col in
11047 (select it1.col1 from it1 where it1.col2 not in (subq));
11048 and subq does subq-mat, and plan is ot1 - it1+firstmatch(ot1),
11049 then:
11050 - t1.prefix_rowcount==1 (due to firstmatch)
11051 - subq is attached to it1, and is evaluated for each row read from
11052 t1, potentially way more than 1.
11053 */
11054 10405 const uint idx = subquery->in_cond_of_tab;
11055
2/4
✓ Branch 0 taken 10405 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10405 times.
✗ Branch 3 not taken.
10405 assert((int)idx >= 0 && idx < parent_join->tables);
11056
1/2
✓ Branch 0 taken 10405 times.
✗ Branch 1 not taken.
10405 trace_parent.add("subq_attached_to_table", true);
11057 10405 QEP_TAB *const parent_tab = &parent_join->qep_tab[idx];
11058
1/2
✓ Branch 0 taken 10405 times.
✗ Branch 1 not taken.
10405 trace_parent.add_utf8_table(parent_tab->table_ref);
11059 10405 parent_fanout = parent_tab->position()->rows_fetched;
11060
4/4
✓ Branch 0 taken 991 times.
✓ Branch 1 taken 9414 times.
✓ Branch 2 taken 965 times.
✓ Branch 3 taken 9440 times.
11396 if ((idx > parent_join->const_tables) &&
11061
2/2
✓ Branch 0 taken 965 times.
✓ Branch 1 taken 26 times.
991 !sj_is_materialize_strategy(parent_tab->position()->sj_strategy))
11062 965 parent_fanout *= parent_tab[-1].position()->prefix_rowcount;
11063 } else {
11064 /*
11065 Subquery is SELECT list, GROUP BY, ORDER BY, HAVING: it is evaluated
11066 at the end of the parent join's execution.
11067 It can be evaluated once per row-before-grouping:
11068 SELECT SUM(t1.col IN (subq)) FROM t1 GROUP BY expr;
11069 or once per row-after-grouping:
11070 SELECT SUM(t1.col) AS s FROM t1 GROUP BY expr HAVING s IN (subq),
11071 SELECT SUM(t1.col) IN (subq) FROM t1 GROUP BY expr
11072 It's hard to tell. We simply assume 'once per
11073 row-before-grouping'.
11074
11075 Another approximation:
11076 SELECT ... HAVING x IN (subq) LIMIT 1
11077 best_rowcount=1 due to LIMIT, though HAVING (and thus the subquery)
11078 may be evaluated many times before HAVING becomes true and the limit
11079 is reached.
11080 */
11081
1/2
✓ Branch 0 taken 5234 times.
✗ Branch 1 not taken.
5234 trace_parent.add("subq_attached_to_join_result", true);
11082 5234 parent_fanout = static_cast<double>(parent_join->best_rowcount);
11083 }
11084 }
11085 19971 subquery_executions *= parent_fanout;
11086
1/2
✓ Branch 0 taken 19971 times.
✗ Branch 1 not taken.
19971 trace_parent.add("fanout", parent_fanout);
11087 19971 const bool cacheable = parent_query_block->is_cacheable();
11088
1/2
✓ Branch 0 taken 19971 times.
✗ Branch 1 not taken.
19971 trace_parent.add("cacheable", cacheable);
11089
2/2
✓ Branch 0 taken 15359 times.
✓ Branch 1 taken 4612 times.
19971 if (cacheable) {
11090 // Parent executed only once
11091 15359 break;
11092 }
11093 /*
11094 Parent query is executed once per outer row => go up to find number of
11095 outer rows. Example:
11096 SELECT ... IN(subq-with-in2exists WHERE ... IN (subq-with-mat))
11097 */
11098 4612 subquery = parent_join->query_expression()->item;
11099
2/2
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 4346 times.
4612 if (subquery == nullptr) {
11100 // derived table, materialized only once
11101 266 break;
11102 }
11103
2/2
✓ Branch 0 taken 4346 times.
✓ Branch 1 taken 15625 times.
24317 } // for(;;)
11104 15625 return subquery_executions;
11105 15625 }
11106
11107 /**
11108 Optimize rollup specification.
11109
11110 Allocate objects needed for rollup processing.
11111
11112 @returns false if success, true if error.
11113 */
11114
11115 377 bool JOIN::optimize_rollup() {
11116 377 tmp_table_param.allow_group_via_temp_table = false;
11117 377 rollup_state = RollupState::INITED;
11118 377 tmp_table_param.group_parts = send_group_parts;
11119 377 return false;
11120 }
11121
11122 /**
11123 Refine the best_rowcount estimation based on what happens after tables
11124 have been joined: LIMIT and type of result sink.
11125 */
11126 1866809 void JOIN::refine_best_rowcount() {
11127 // If plan is const, 0 or 1 rows should be returned
11128
3/4
✓ Branch 0 taken 99398 times.
✓ Branch 1 taken 1767447 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 99398 times.
1866809 assert(!plan_is_const() || best_rowcount <= 1);
11129
11130
2/2
✓ Branch 0 taken 99398 times.
✓ Branch 1 taken 1767457 times.
1866845 if (plan_is_const()) return;
11131
11132 /*
11133 If a derived table, or a member of a UNION which itself forms a derived
11134 table:
11135 setting estimate to 0 or 1 row would mark the derived table as const.
11136 The row count is bumped to the nearest higher value, so that the
11137 query block will not be evaluated during optimization.
11138 */
11139
4/4
✓ Branch 0 taken 366931 times.
✓ Branch 1 taken 1400526 times.
✓ Branch 2 taken 3613 times.
✓ Branch 3 taken 1763810 times.
2134354 if (best_rowcount <= 1 &&
11140
2/2
✓ Branch 0 taken 3613 times.
✓ Branch 1 taken 363284 times.
366931 query_block->master_query_expression()->first_query_block()->linkage ==
11141 DERIVED_TABLE_TYPE)
11142 3613 best_rowcount = PLACEHOLDER_TABLE_ROW_ESTIMATE;
11143
11144 /*
11145 There will be no more rows than defined in the LIMIT clause. Use it
11146 as an estimate. If LIMIT 1 is specified, the query block will be
11147 considered "const", with actual row count 0 or 1.
11148 */
11149 1767423 best_rowcount = std::min(best_rowcount, query_expression()->select_limit_cnt);
11150 }
11151
11152 147993 mem_root_deque<Item *> *JOIN::get_current_fields() {
11153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 147993 times.
147993 assert((int)current_ref_item_slice >= 0);
11154
2/2
✓ Branch 0 taken 147989 times.
✓ Branch 1 taken 4 times.
147993 if (current_ref_item_slice == REF_SLICE_SAVED_BASE) return fields;
11155 4 return &tmp_fields[current_ref_item_slice];
11156 }
11157
11158 515865388 const Cost_model_server *JOIN::cost_model() const {
11159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 515865388 times.
515865388 assert(thd != nullptr);
11160 515865388 return thd->cost_model();
11161 }
11162
11163 /**
11164 @} (end of group Query_Optimizer)
11165 */
11166
11167 /**
11168 This function is used to get the key length of Item object on
11169 which one tmp field will be created during create_tmp_table.
11170 This function references KEY_PART_INFO::init_from_field().
11171
11172 @param item A inner item of outer join
11173
11174 @return The length of a item to be as a key of a temp table
11175 */
11176
11177 9514 static uint32 get_key_length_tmp_table(Item *item) {
11178 9514 uint32 len = 0;
11179
11180 9514 item = item->real_item();
11181
2/2
✓ Branch 0 taken 8012 times.
✓ Branch 1 taken 1502 times.
9514 if (item->type() == Item::FIELD_ITEM)
11182 8012 len = ((Item_field *)item)->field->key_length();
11183 else
11184 1502 len = item->max_length;
11185
11186
2/2
✓ Branch 0 taken 8380 times.
✓ Branch 1 taken 1134 times.
9514 if (item->is_nullable()) len += HA_KEY_NULL_LENGTH;
11187
11188 // references KEY_PART_INFO::init_from_field()
11189 9514 enum_field_types type = item->data_type();
11190
6/6
✓ Branch 0 taken 9235 times.
✓ Branch 1 taken 279 times.
✓ Branch 2 taken 7594 times.
✓ Branch 3 taken 1641 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 7582 times.
9514 if (type == MYSQL_TYPE_BLOB || type == MYSQL_TYPE_VARCHAR ||
11191 type == MYSQL_TYPE_GEOMETRY)
11192 1932 len += HA_KEY_BLOB_LENGTH;
11193
11194 9514 return len;
11195 }
11196
11197 4753192 bool evaluate_during_optimization(const Item *item, const Query_block *select) {
11198 /*
11199 Should only be called on items that are const_for_execution(), as those
11200 items are the only ones that are allowed to be evaluated during optimization
11201 in the first place.
11202
11203 Additionally, allow items that only access tables in JOIN::const_table_map.
11204 This should not be necessary, but the const_for_execution() property is not
11205 always updated correctly by update_used_tables() for certain subqueries.
11206 */
11207
3/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 4753223 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 68 times.
4753192 assert(item->const_for_execution() ||
11208 (item->used_tables() & ~select->join->const_table_map) == 0);
11209
11210 // If the Item does not access any tables, it can always be evaluated.
11211
2/2
✓ Branch 0 taken 4362384 times.
✓ Branch 1 taken 390970 times.
4753291 if (item->const_item()) return true;
11212
11213
4/4
✓ Branch 0 taken 17760 times.
✓ Branch 1 taken 373230 times.
✓ Branch 2 taken 17743 times.
✓ Branch 3 taken 14 times.
390970 return !item->has_subquery() || (select->active_options() &
11214 390987 OPTION_NO_SUBQUERY_DURING_OPTIMIZATION) == 0;
11215 }
11216